From 52241469d960e2b042a2da00e96da0aa22d3ea62 Mon Sep 17 00:00:00 2001 From: junchao Date: Wed, 30 Sep 2020 17:52:24 +0800 Subject: [PATCH 1/2] Add patches for i2c API --- ...14-mlxsw-i2c-Fix-comment-misspelling.patch | 31 +++ ...-input-parameter-name-in-initializat.patch | 33 +++ ...-input-parameters-list-of-command-AP.patch | 199 ++++++++++++++++++ ...-initialization-by-querying-resource.patch | 53 +++++ ...nitialization-with-querying-firmware.patch | 47 +++++ ...flexible-setting-of-I2C-transactions.patch | 198 +++++++++++++++++ ...different-thermal-polling-time-based.patch | 70 ++++++ .../0021-mlxsw-i2c-Add-device-info-log.patch | 31 +++ patch/series | 8 + 9 files changed, 670 insertions(+) create mode 100755 patch/0014-mlxsw-i2c-Fix-comment-misspelling.patch create mode 100755 patch/0015-mlxsw-i2c-Modify-input-parameter-name-in-initializat.patch create mode 100755 patch/0016-mlxsw-i2c-Extend-input-parameters-list-of-command-AP.patch create mode 100755 patch/0017-mlxsw-i2c-Extend-initialization-by-querying-resource.patch create mode 100755 patch/0018-mlxsw-i2c-Extend-initialization-with-querying-firmware.patch create mode 100755 patch/0019-mlxsw-i2c-Allow-flexible-setting-of-I2C-transactions.patch create mode 100755 patch/0020-mlxsw-core-Set-different-thermal-polling-time-based.patch create mode 100755 patch/0021-mlxsw-i2c-Add-device-info-log.patch diff --git a/patch/0014-mlxsw-i2c-Fix-comment-misspelling.patch b/patch/0014-mlxsw-i2c-Fix-comment-misspelling.patch new file mode 100755 index 000000000..4da71492f --- /dev/null +++ b/patch/0014-mlxsw-i2c-Fix-comment-misspelling.patch @@ -0,0 +1,31 @@ +From bb549427f1fcf0ac05d6d72546847b1d98eaf771 Mon Sep 17 00:00:00 2001 +From: Vadim Pasternak +Date: Sun, 3 Mar 2019 09:12:12 +0000 +Subject: [PATCH backport v4.19 1/8] mlxsw: i2c: Fix comment misspelling + +Fix comment for mlxsw_i2c_write_cmd(). + +Signed-off-by: Vadim Pasternak +Acked-by: Jiri Pirko +Signed-off-by: Ido Schimmel +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/mellanox/mlxsw/i2c.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlxsw/i2c.c b/drivers/net/ethernet/mellanox/mlxsw/i2c.c +index 798bd5aca384..cdeee35b829b 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/i2c.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/i2c.c +@@ -167,7 +167,7 @@ static int mlxsw_i2c_wait_go_bit(struct i2c_client *client, + return err > 0 ? 0 : err; + } + +-/* Routine posts a command to ASIC though mail box. */ ++/* Routine posts a command to ASIC through mail box. */ + static int mlxsw_i2c_write_cmd(struct i2c_client *client, + struct mlxsw_i2c *mlxsw_i2c, + int immediate) +-- +2.11.0 + diff --git a/patch/0015-mlxsw-i2c-Modify-input-parameter-name-in-initializat.patch b/patch/0015-mlxsw-i2c-Modify-input-parameter-name-in-initializat.patch new file mode 100755 index 000000000..8f6ebb9bd --- /dev/null +++ b/patch/0015-mlxsw-i2c-Modify-input-parameter-name-in-initializat.patch @@ -0,0 +1,33 @@ +From 1d4de996de20444fdb4b2c1ab63bf7fa981dc997 Mon Sep 17 00:00:00 2001 +From: Vadim Pasternak +Date: Sun, 3 Mar 2019 09:12:14 +0000 +Subject: [PATCH backport v4.19 2/8] mlxsw: i2c: Modify input parameter name in + initialization API + +Change input parameter name "resource" to "res" in mlxsw_i2c_init() in +order to align it with mlxsw_pci_init(). + +Signed-off-by: Vadim Pasternak +Acked-by: Jiri Pirko +Signed-off-by: Ido Schimmel +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/mellanox/mlxsw/i2c.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlxsw/i2c.c b/drivers/net/ethernet/mellanox/mlxsw/i2c.c +index cdeee35b829b..0a53c3bff388 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/i2c.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/i2c.c +@@ -414,7 +414,7 @@ static int mlxsw_i2c_skb_transmit(void *bus_priv, struct sk_buff *skb, + static int + mlxsw_i2c_init(void *bus_priv, struct mlxsw_core *mlxsw_core, + const struct mlxsw_config_profile *profile, +- struct mlxsw_res *resources) ++ struct mlxsw_res *res) + { + struct mlxsw_i2c *mlxsw_i2c = bus_priv; + +-- +2.11.0 + diff --git a/patch/0016-mlxsw-i2c-Extend-input-parameters-list-of-command-AP.patch b/patch/0016-mlxsw-i2c-Extend-input-parameters-list-of-command-AP.patch new file mode 100755 index 000000000..0ae87c213 --- /dev/null +++ b/patch/0016-mlxsw-i2c-Extend-input-parameters-list-of-command-AP.patch @@ -0,0 +1,199 @@ +From 00c82f8ba6cce3434f5f83611ab149cf02d3f801 Mon Sep 17 00:00:00 2001 +From: Vadim Pasternak +Date: Sun, 3 Mar 2019 09:12:15 +0000 +Subject: [PATCH backport v4.19 3/8] mlxsw: i2c: Extend input parameters list + of command API + +Extend input parameters list of command API in mlxsw_i2c_cmd() in order +to support initialization commands. Up until now, only access commands +were supported by I2C driver. + +Signed-off-by: Vadim Pasternak +Acked-by: Jiri Pirko +Signed-off-by: Ido Schimmel +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/mellanox/mlxsw/i2c.c | 120 +++++++++++++++++++++++++----- + 1 file changed, 101 insertions(+), 19 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlxsw/i2c.c b/drivers/net/ethernet/mellanox/mlxsw/i2c.c +index 0a53c3bff388..3f95692be816 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/i2c.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/i2c.c +@@ -20,8 +20,10 @@ + #define MLXSW_I2C_CIR2_OFF_STATUS (MLXSW_I2C_CIR2_BASE + \ + MLXSW_I2C_CIR_STATUS_OFF) + #define MLXSW_I2C_OPMOD_SHIFT 12 ++#define MLXSW_I2C_EVENT_BIT_SHIFT 22 + #define MLXSW_I2C_GO_BIT_SHIFT 23 + #define MLXSW_I2C_CIR_CTRL_STATUS_SHIFT 24 ++#define MLXSW_I2C_EVENT_BIT BIT(MLXSW_I2C_EVENT_BIT_SHIFT) + #define MLXSW_I2C_GO_BIT BIT(MLXSW_I2C_GO_BIT_SHIFT) + #define MLXSW_I2C_GO_OPMODE BIT(MLXSW_I2C_OPMOD_SHIFT) + #define MLXSW_I2C_SET_IMM_CMD (MLXSW_I2C_GO_OPMODE | \ +@@ -33,6 +35,9 @@ + #define MLXSW_I2C_TLV_HDR_SIZE 0x10 + #define MLXSW_I2C_ADDR_WIDTH 4 + #define MLXSW_I2C_PUSH_CMD_SIZE (MLXSW_I2C_ADDR_WIDTH + 4) ++#define MLXSW_I2C_SET_EVENT_CMD (MLXSW_I2C_EVENT_BIT) ++#define MLXSW_I2C_PUSH_EVENT_CMD (MLXSW_I2C_GO_BIT | \ ++ MLXSW_I2C_SET_EVENT_CMD) + #define MLXSW_I2C_READ_SEMA_SIZE 4 + #define MLXSW_I2C_PREP_SIZE (MLXSW_I2C_ADDR_WIDTH + 28) + #define MLXSW_I2C_MBOX_SIZE 20 +@@ -44,6 +49,7 @@ + #define MLXSW_I2C_BLK_MAX 32 + #define MLXSW_I2C_RETRY 5 + #define MLXSW_I2C_TIMEOUT_MSECS 5000 ++#define MLXSW_I2C_MAX_DATA_SIZE 256 + + /** + * struct mlxsw_i2c - device private data: +@@ -213,6 +219,66 @@ static int mlxsw_i2c_write_cmd(struct i2c_client *client, + return 0; + } + ++/* Routine posts initialization command to ASIC through mail box. */ ++static int ++mlxsw_i2c_write_init_cmd(struct i2c_client *client, ++ struct mlxsw_i2c *mlxsw_i2c, u16 opcode, u32 in_mod) ++{ ++ __be32 push_cmd_buf[MLXSW_I2C_PUSH_CMD_SIZE / 4] = { ++ 0, cpu_to_be32(MLXSW_I2C_PUSH_EVENT_CMD) ++ }; ++ __be32 prep_cmd_buf[MLXSW_I2C_PREP_SIZE / 4] = { ++ 0, 0, 0, 0, 0, 0, ++ cpu_to_be32(client->adapter->nr & 0xffff), ++ cpu_to_be32(MLXSW_I2C_SET_EVENT_CMD) ++ }; ++ struct i2c_msg push_cmd = ++ MLXSW_I2C_WRITE_MSG(client, push_cmd_buf, ++ MLXSW_I2C_PUSH_CMD_SIZE); ++ struct i2c_msg prep_cmd = ++ MLXSW_I2C_WRITE_MSG(client, prep_cmd_buf, MLXSW_I2C_PREP_SIZE); ++ u8 status; ++ int err; ++ ++ push_cmd_buf[1] = cpu_to_be32(MLXSW_I2C_PUSH_EVENT_CMD | opcode); ++ prep_cmd_buf[3] = cpu_to_be32(in_mod); ++ prep_cmd_buf[7] = cpu_to_be32(MLXSW_I2C_GO_BIT | opcode); ++ mlxsw_i2c_set_slave_addr((u8 *)prep_cmd_buf, ++ MLXSW_I2C_CIR2_BASE); ++ mlxsw_i2c_set_slave_addr((u8 *)push_cmd_buf, ++ MLXSW_I2C_CIR2_OFF_STATUS); ++ ++ /* Prepare Command Interface Register for transaction */ ++ err = i2c_transfer(client->adapter, &prep_cmd, 1); ++ if (err < 0) ++ return err; ++ else if (err != 1) ++ return -EIO; ++ ++ /* Write out Command Interface Register GO bit to push transaction */ ++ err = i2c_transfer(client->adapter, &push_cmd, 1); ++ if (err < 0) ++ return err; ++ else if (err != 1) ++ return -EIO; ++ ++ /* Wait until go bit is cleared. */ ++ err = mlxsw_i2c_wait_go_bit(client, mlxsw_i2c, &status); ++ if (err) { ++ dev_err(&client->dev, "HW semaphore is not released"); ++ return err; ++ } ++ ++ /* Validate transaction completion status. */ ++ if (status) { ++ dev_err(&client->dev, "Bad transaction completion status %x\n", ++ status); ++ return -EIO; ++ } ++ ++ return 0; ++} ++ + /* Routine obtains mail box offsets from ASIC register space. */ + static int mlxsw_i2c_get_mbox(struct i2c_client *client, + struct mlxsw_i2c *mlxsw_i2c) +@@ -310,8 +376,8 @@ mlxsw_i2c_write(struct device *dev, size_t in_mbox_size, u8 *in_mbox, int num, + + /* Routine executes I2C command. */ + static int +-mlxsw_i2c_cmd(struct device *dev, size_t in_mbox_size, u8 *in_mbox, +- size_t out_mbox_size, u8 *out_mbox, u8 *status) ++mlxsw_i2c_cmd(struct device *dev, u16 opcode, u32 in_mod, size_t in_mbox_size, ++ u8 *in_mbox, size_t out_mbox_size, u8 *out_mbox, u8 *status) + { + struct i2c_client *client = to_i2c_client(dev); + struct mlxsw_i2c *mlxsw_i2c = i2c_get_clientdata(client); +@@ -326,24 +392,40 @@ mlxsw_i2c_cmd(struct device *dev, size_t in_mbox_size, u8 *in_mbox, + + WARN_ON(in_mbox_size % sizeof(u32) || out_mbox_size % sizeof(u32)); + +- reg_size = mlxsw_i2c_get_reg_size(in_mbox); +- num = reg_size / MLXSW_I2C_BLK_MAX; +- if (reg_size % MLXSW_I2C_BLK_MAX) +- num++; ++ 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++; + +- if (mutex_lock_interruptible(&mlxsw_i2c->cmd.lock) < 0) { +- dev_err(&client->dev, "Could not acquire lock"); +- return -EINVAL; +- } ++ 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) +- goto cmd_fail; ++ err = mlxsw_i2c_write(dev, reg_size, in_mbox, num, status); ++ if (err) ++ goto cmd_fail; ++ ++ /* No out mailbox is case of write transaction. */ ++ if (!out_mbox) { ++ mutex_unlock(&mlxsw_i2c->cmd.lock); ++ return 0; ++ } ++ } else { ++ /* No input mailbox is case of initialization query command. */ ++ reg_size = MLXSW_I2C_MAX_DATA_SIZE; ++ num = reg_size / MLXSW_I2C_BLK_MAX; + +- /* No out mailbox is case of write transaction. */ +- if (!out_mbox) { +- mutex_unlock(&mlxsw_i2c->cmd.lock); +- return 0; ++ 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); ++ if (err) ++ goto cmd_fail; + } + + /* Send read transaction to get output mailbox content. */ +@@ -395,8 +477,8 @@ static int mlxsw_i2c_cmd_exec(void *bus_priv, u16 opcode, u8 opcode_mod, + { + struct mlxsw_i2c *mlxsw_i2c = bus_priv; + +- return mlxsw_i2c_cmd(mlxsw_i2c->dev, in_mbox_size, in_mbox, +- out_mbox_size, out_mbox, status); ++ return mlxsw_i2c_cmd(mlxsw_i2c->dev, opcode, in_mod, in_mbox_size, ++ in_mbox, out_mbox_size, out_mbox, status); + } + + static bool mlxsw_i2c_skb_transmit_busy(void *bus_priv, +-- +2.11.0 + diff --git a/patch/0017-mlxsw-i2c-Extend-initialization-by-querying-resource.patch b/patch/0017-mlxsw-i2c-Extend-initialization-by-querying-resource.patch new file mode 100755 index 000000000..9a5953f40 --- /dev/null +++ b/patch/0017-mlxsw-i2c-Extend-initialization-by-querying-resource.patch @@ -0,0 +1,53 @@ +From 31f7829248a15f3b9faed7e3bac186b4dbb223cd Mon Sep 17 00:00:00 2001 +From: Vadim Pasternak +Date: Sun, 3 Mar 2019 09:12:16 +0000 +Subject: [PATCH backport v4.19 4/8] mlxsw: i2c: Extend initialization by + querying resources data + +Extend initialization flow by query requests for chip resources data in +order to obtain chip's specific capabilities, like the number of ports. + +Signed-off-by: Vadim Pasternak +Acked-by: Jiri Pirko +Signed-off-by: Ido Schimmel +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/mellanox/mlxsw/i2c.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlxsw/i2c.c b/drivers/net/ethernet/mellanox/mlxsw/i2c.c +index 3f95692be816..d46a655e3001 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/i2c.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/i2c.c +@@ -14,6 +14,7 @@ + #include "cmd.h" + #include "core.h" + #include "i2c.h" ++#include "resources.h" + + #define MLXSW_I2C_CIR2_BASE 0x72000 + #define MLXSW_I2C_CIR_STATUS_OFF 0x18 +@@ -499,10 +500,19 @@ mlxsw_i2c_init(void *bus_priv, struct mlxsw_core *mlxsw_core, + struct mlxsw_res *res) + { + struct mlxsw_i2c *mlxsw_i2c = bus_priv; ++ char *mbox; ++ int err; + + mlxsw_i2c->core = mlxsw_core; + +- return 0; ++ mbox = mlxsw_cmd_mbox_alloc(); ++ if (!mbox) ++ return -ENOMEM; ++ ++ err = mlxsw_core_resources_query(mlxsw_core, mbox, res); ++ ++ mlxsw_cmd_mbox_free(mbox); ++ return err; + } + + static void mlxsw_i2c_fini(void *bus_priv) +-- +2.11.0 + diff --git a/patch/0018-mlxsw-i2c-Extend-initialization-with-querying-firmware.patch b/patch/0018-mlxsw-i2c-Extend-initialization-with-querying-firmware.patch new file mode 100755 index 000000000..ee29e1745 --- /dev/null +++ b/patch/0018-mlxsw-i2c-Extend-initialization-with-querying-firmware.patch @@ -0,0 +1,47 @@ +From 4b70b08c3bd12b6819bf438b9ac5c646167f8803 Mon Sep 17 00:00:00 2001 +From: Vadim Pasternak +Date: Wed, 29 May 2019 11:47:15 +0300 +Subject: [PATCH backport v4.19 5/8] mlxsw: i2c: Extend initialization with + querying firmware info + +Extend initialization flow with query request for firmware info in +order to obtain firmware version info. +This info is to be provided to minimal driver to support ethtool +get_drvinfo() interface. + +Signed-off-by: Vadim Pasternak +Acked-by: Jiri Pirko +Signed-off-by: Ido Schimmel +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/mellanox/mlxsw/i2c.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/drivers/net/ethernet/mellanox/mlxsw/i2c.c b/drivers/net/ethernet/mellanox/mlxsw/i2c.c +index d46a655e3001..472352977527 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/i2c.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/i2c.c +@@ -509,8 +509,20 @@ mlxsw_i2c_init(void *bus_priv, struct mlxsw_core *mlxsw_core, + if (!mbox) + return -ENOMEM; + ++ err = mlxsw_cmd_query_fw(mlxsw_core, mbox); ++ if (err) ++ goto mbox_put; ++ ++ mlxsw_i2c->bus_info.fw_rev.major = ++ mlxsw_cmd_mbox_query_fw_fw_rev_major_get(mbox); ++ mlxsw_i2c->bus_info.fw_rev.minor = ++ mlxsw_cmd_mbox_query_fw_fw_rev_minor_get(mbox); ++ mlxsw_i2c->bus_info.fw_rev.subminor = ++ mlxsw_cmd_mbox_query_fw_fw_rev_subminor_get(mbox); ++ + err = mlxsw_core_resources_query(mlxsw_core, mbox, res); + ++mbox_put: + mlxsw_cmd_mbox_free(mbox); + return err; + } +-- +2.11.0 + diff --git a/patch/0019-mlxsw-i2c-Allow-flexible-setting-of-I2C-transactions.patch b/patch/0019-mlxsw-i2c-Allow-flexible-setting-of-I2C-transactions.patch new file mode 100755 index 000000000..20709f4bf --- /dev/null +++ b/patch/0019-mlxsw-i2c-Allow-flexible-setting-of-I2C-transactions.patch @@ -0,0 +1,198 @@ +From c391e6804e21e80535dae3eb79bc9463552e2ab2 Mon Sep 17 00:00:00 2001 +From: Vadim Pasternak +Date: Wed, 29 May 2019 11:47:16 +0300 +Subject: [PATCH backport v4.19 6/8] mlxsw: i2c: Allow flexible setting of I2C + transactions size + +Current implementation uses fixed size of I2C data transaction buffer. +Allow to set size of I2C transactions according to I2C physical adapter +capability. For that purpose adapter read and write size is obtained +from the I2C physical adapter and buffer size is set according to the +minimum of these two values. If adapter does not provide such info, +default buffer size is to be used. +It allows to improve performance of I2C access to silicon when long +size transactions are used. + +Signed-off-by: Vadim Pasternak +Acked-by: Jiri Pirko +Signed-off-by: Ido Schimmel +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/mellanox/mlxsw/i2c.c | 64 ++++++++++++++++++++++--------- + 1 file changed, 46 insertions(+), 18 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlxsw/i2c.c b/drivers/net/ethernet/mellanox/mlxsw/i2c.c +index 472352977527..ac4f381f0f76 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,27 @@ 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 +406,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 +427,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 +443,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 +557,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 +566,22 @@ static int mlxsw_i2c_probe(struct i2c_client *client, + if (!mlxsw_i2c) + return -ENOMEM; + ++ if (quirks) { ++ if ((quirks->max_read_len && ++ quirks->max_read_len < MLXSW_I2C_BLK_DEF) || ++ (quirks->max_write_len && ++ quirks->max_write_len < MLXSW_I2C_BLK_DEF)) { ++ dev_err(&client->dev, "Insufficient transaction buffer length\n"); ++ return -EOPNOTSUPP; ++ } ++ ++ 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); + +-- +2.11.0 + diff --git a/patch/0020-mlxsw-core-Set-different-thermal-polling-time-based.patch b/patch/0020-mlxsw-core-Set-different-thermal-polling-time-based.patch new file mode 100755 index 000000000..02bbceaf2 --- /dev/null +++ b/patch/0020-mlxsw-core-Set-different-thermal-polling-time-based.patch @@ -0,0 +1,70 @@ +From 59a688a401d122af904acbe658502dcbbac813d5 Mon Sep 17 00:00:00 2001 +From: Vadim Pasternak +Date: Wed, 13 Feb 2019 11:28:48 +0000 +Subject: [PATCH backport v4.19 7/8] mlxsw: core: Set different thermal polling + time based on bus frequency capability + +Add low frequency bus capability in order to allow core functionality +separation based on bus type. Driver could run over PCIe, which is +considered as high frequency bus or I2C, which is considered as low +frequency bus. In the last case time setting, for example, for thermal +polling interval, should be increased. + +Use different thermal monitoring based on bus type. For I2C bus time is +set to 20 seconds, while for PCIe 1 second polling interval is used. + +Signed-off-by: Vadim Pasternak +Reviewed-by: Jiri Pirko +Signed-off-by: Ido Schimmel +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 6 +++--- + drivers/net/ethernet/mellanox/mlxsw/i2c.c | 1 + + 2 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c +index 775343a2568e..d77c4c82b23a 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c +@@ -807,7 +807,7 @@ mlxsw_thermal_module_tz_init(struct mlxsw_thermal_module *module_tz) + return err; + } + +- module_tz->mode = THERMAL_DEVICE_DISABLED; ++ module_tz->mode = THERMAL_DEVICE_ENABLED; + return 0; + } + +@@ -925,7 +925,7 @@ mlxsw_thermal_gearbox_tz_init(struct mlxsw_thermal_module *gearbox_tz) + if (IS_ERR(gearbox_tz->tzdev)) + return PTR_ERR(gearbox_tz->tzdev); + +- gearbox_tz->mode = THERMAL_DEVICE_DISABLED; ++ gearbox_tz->mode = THERMAL_DEVICE_ENABLED; + return 0; + } + +@@ -1095,7 +1095,7 @@ int mlxsw_thermal_init(struct mlxsw_core *core, + if (err) + goto err_unreg_modules_tzdev; + +- thermal->mode = THERMAL_DEVICE_DISABLED; ++ thermal->mode = THERMAL_DEVICE_ENABLED; + thermal->initializing = false; + *p_thermal = thermal; + return 0; +diff --git a/drivers/net/ethernet/mellanox/mlxsw/i2c.c b/drivers/net/ethernet/mellanox/mlxsw/i2c.c +index ac4f381f0f76..95f408d0e103 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/i2c.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/i2c.c +@@ -635,6 +635,7 @@ static int mlxsw_i2c_probe(struct i2c_client *client, + mlxsw_i2c->bus_info.device_kind = id->name; + mlxsw_i2c->bus_info.device_name = client->name; + mlxsw_i2c->bus_info.dev = &client->dev; ++ mlxsw_i2c->bus_info.low_frequency = true; + mlxsw_i2c->dev = &client->dev; + + err = mlxsw_core_bus_device_register(&mlxsw_i2c->bus_info, +-- +2.11.0 + diff --git a/patch/0021-mlxsw-i2c-Add-device-info-log.patch b/patch/0021-mlxsw-i2c-Add-device-info-log.patch new file mode 100755 index 000000000..c63d9dd44 --- /dev/null +++ b/patch/0021-mlxsw-i2c-Add-device-info-log.patch @@ -0,0 +1,31 @@ +From 6360f7272a370eee26118d46d963bb91ea36dfa2 Mon Sep 17 00:00:00 2001 +From: Vadim Pasternak +Date: Tue, 29 Sep 2020 08:39:38 +0300 +Subject: [PATCH backport v4.19 8/8] mlxsw: i2c: Add device info log + +Add info log to probe() routine to report firmware setting in 'dmesg'. + +Signed-off-by: Vadim Pasternak +--- + drivers/net/ethernet/mellanox/mlxsw/i2c.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/ethernet/mellanox/mlxsw/i2c.c b/drivers/net/ethernet/mellanox/mlxsw/i2c.c +index 95f408d0e103..e04d521d9376 100644 +--- a/drivers/net/ethernet/mellanox/mlxsw/i2c.c ++++ b/drivers/net/ethernet/mellanox/mlxsw/i2c.c +@@ -646,6 +646,11 @@ static int mlxsw_i2c_probe(struct i2c_client *client, + return err; + } + ++ dev_info(&client->dev, "Firmware revision: %d.%d.%d\n", ++ mlxsw_i2c->bus_info.fw_rev.major, ++ mlxsw_i2c->bus_info.fw_rev.minor, ++ mlxsw_i2c->bus_info.fw_rev.subminor); ++ + return 0; + + errout: +-- +2.11.0 + diff --git a/patch/series b/patch/series index be08a1be8..46af948e9 100755 --- a/patch/series +++ b/patch/series @@ -61,4 +61,12 @@ driver-ixgbe-external-phy.patch 0011-mlxsw-core-thermal-Separate-temperature-trend-read-c.patch 0012-Add-support-for-new-transceivers-types-QSFP-DD-and-Q.patch 0013-watchdog-mlx-wdt-support-new-watchdog-type-with-long.patch +0014-mlxsw-i2c-Fix-comment-misspelling.patch +0015-mlxsw-i2c-Modify-input-parameter-name-in-initializat.patch +0016-mlxsw-i2c-Extend-input-parameters-list-of-command-AP.patch +0017-mlxsw-i2c-Extend-initialization-by-querying-resource.patch +0018-mlxsw-i2c-Extend-initialization-with-querying-firmware.patch +0019-mlxsw-i2c-Allow-flexible-setting-of-I2C-transactions.patch +0020-mlxsw-core-Set-different-thermal-polling-time-based.patch +0021-mlxsw-i2c-Add-device-info-log.patch From 3a2359747d24c91daab6b836ad0f45487c8b31e6 Mon Sep 17 00:00:00 2001 From: Volodymyr Samotiy Date: Tue, 20 Oct 2020 18:11:08 +0300 Subject: [PATCH 2/2] [Mellanox] Add patches for i2c API * Fix review comments Signed-off-by: Volodymyr Samotiy --- .../0021-mlxsw-i2c-Add-device-info-log.patch | 31 ------------------- patch/series | 1 - 2 files changed, 32 deletions(-) delete mode 100755 patch/0021-mlxsw-i2c-Add-device-info-log.patch diff --git a/patch/0021-mlxsw-i2c-Add-device-info-log.patch b/patch/0021-mlxsw-i2c-Add-device-info-log.patch deleted file mode 100755 index c63d9dd44..000000000 --- a/patch/0021-mlxsw-i2c-Add-device-info-log.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 6360f7272a370eee26118d46d963bb91ea36dfa2 Mon Sep 17 00:00:00 2001 -From: Vadim Pasternak -Date: Tue, 29 Sep 2020 08:39:38 +0300 -Subject: [PATCH backport v4.19 8/8] mlxsw: i2c: Add device info log - -Add info log to probe() routine to report firmware setting in 'dmesg'. - -Signed-off-by: Vadim Pasternak ---- - drivers/net/ethernet/mellanox/mlxsw/i2c.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/drivers/net/ethernet/mellanox/mlxsw/i2c.c b/drivers/net/ethernet/mellanox/mlxsw/i2c.c -index 95f408d0e103..e04d521d9376 100644 ---- a/drivers/net/ethernet/mellanox/mlxsw/i2c.c -+++ b/drivers/net/ethernet/mellanox/mlxsw/i2c.c -@@ -646,6 +646,11 @@ static int mlxsw_i2c_probe(struct i2c_client *client, - return err; - } - -+ dev_info(&client->dev, "Firmware revision: %d.%d.%d\n", -+ mlxsw_i2c->bus_info.fw_rev.major, -+ mlxsw_i2c->bus_info.fw_rev.minor, -+ mlxsw_i2c->bus_info.fw_rev.subminor); -+ - return 0; - - errout: --- -2.11.0 - diff --git a/patch/series b/patch/series index 46af948e9..03c88a4ae 100755 --- a/patch/series +++ b/patch/series @@ -68,5 +68,4 @@ driver-ixgbe-external-phy.patch 0018-mlxsw-i2c-Extend-initialization-with-querying-firmware.patch 0019-mlxsw-i2c-Allow-flexible-setting-of-I2C-transactions.patch 0020-mlxsw-core-Set-different-thermal-polling-time-based.patch -0021-mlxsw-i2c-Add-device-info-log.patch