Netdev Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH net-next RFC 0/3] Add mlx5 devices FW upgrade reset support
@ 2020-01-14 15:55 Moshe Shemesh
  2020-01-14 15:55 ` [PATCH net-next RFC 1/3] net/mlx5: Add structure layout and defines for MFRL register Moshe Shemesh
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Moshe Shemesh @ 2020-01-14 15:55 UTC (permalink / raw)
  To: David S. Miller; +Cc: Alexander Duyck, netdev, linux-kernel, Moshe Shemesh

This patchset adds support for FW upgrade.
On devlink reload, if a pending FW image is found, the driver will perform
a FW upgrade reset flow to activate the pending FW image.

Sending as RFC because the FW activation reset requires a pci link
toggling. Although it works and we verify that the device is the only
device on the pcie bridge before allowing such reset, as already done by
other drivers [1], we would like to get some feedback on the last patch
of this series.

[1] function trigger_sbr() at drivers/infiniband/hw/hfi1/pcie.c

Moshe Shemesh (3):
  net/mlx5: Add structure layout and defines for MFRL register
  net/mlx5: Add functions to set/query MFRL register
  net/mlx5: Add FW upgrade reset support

 drivers/net/ethernet/mellanox/mlx5/core/devlink.c  | 81 +++++++++++++++++++++-
 drivers/net/ethernet/mellanox/mlx5/core/fw.c       | 44 ++++++++++++
 .../net/ethernet/mellanox/mlx5/core/mlx5_core.h    |  2 +
 include/linux/mlx5/driver.h                        |  1 +
 include/linux/mlx5/mlx5_ifc.h                      | 17 +++++
 5 files changed, 144 insertions(+), 1 deletion(-)

-- 
1.8.3.1


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

* [PATCH net-next RFC 1/3] net/mlx5: Add structure layout and defines for MFRL register
  2020-01-14 15:55 [PATCH net-next RFC 0/3] Add mlx5 devices FW upgrade reset support Moshe Shemesh
@ 2020-01-14 15:55 ` Moshe Shemesh
  2020-01-14 15:55 ` [PATCH net-next RFC 2/3] net/mlx5: Add functions to set/query " Moshe Shemesh
  2020-01-14 15:55 ` [PATCH net-next RFC 3/3] net/mlx5: Add FW upgrade reset support Moshe Shemesh
  2 siblings, 0 replies; 7+ messages in thread
From: Moshe Shemesh @ 2020-01-14 15:55 UTC (permalink / raw)
  To: David S. Miller; +Cc: Alexander Duyck, netdev, linux-kernel, Moshe Shemesh

Add needed structure layouts and defines for MFRL (Management Firmware
Reset Level) register. This structure will be used for the firmware
upgrade and reset flow in the downstream patches.

Signed-off-by: Moshe Shemesh <moshe@mellanox.com>
---
 include/linux/mlx5/driver.h   |  1 +
 include/linux/mlx5/mlx5_ifc.h | 17 +++++++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index 583733a..268ecfd 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -130,6 +130,7 @@ enum {
 	MLX5_REG_NODE_DESC	 = 0x6001,
 	MLX5_REG_HOST_ENDIANNESS = 0x7004,
 	MLX5_REG_MCIA		 = 0x9014,
+	MLX5_REG_MFRL		 = 0x9028,
 	MLX5_REG_MLCR		 = 0x902b,
 	MLX5_REG_MTRC_CAP	 = 0x9040,
 	MLX5_REG_MTRC_CONF	 = 0x9041,
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index 178757c..7684537 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -9584,6 +9584,22 @@ struct mlx5_ifc_mcda_reg_bits {
 	u8         data[0][0x20];
 };
 
+enum {
+	MLX5_MFRL_REG_RESET_LEVEL0  = 0x1,
+	MLX5_MFRL_REG_RESET_LEVEL3  = 0x8,
+	MLX5_MFRL_REG_RESET_LEVEL6  = 0x40,
+};
+
+struct mlx5_ifc_mfrl_reg_bits {
+	u8         reserved_at_0[0x20];
+
+	u8         reserved_at_20[0x5];
+	u8         rst_type_sel[0x3];
+	u8         reserved_at_28[0x8];
+	u8         reset_type[0x8];
+	u8         reset_level[0x8];
+};
+
 struct mlx5_ifc_mirc_reg_bits {
 	u8         reserved_at_0[0x18];
 	u8         status_code[0x8];
@@ -9646,6 +9662,7 @@ struct mlx5_ifc_mirc_reg_bits {
 	struct mlx5_ifc_mcqi_reg_bits mcqi_reg;
 	struct mlx5_ifc_mcc_reg_bits mcc_reg;
 	struct mlx5_ifc_mcda_reg_bits mcda_reg;
+	struct mlx5_ifc_mfrl_reg_bits mfrl_reg;
 	struct mlx5_ifc_mirc_reg_bits mirc_reg;
 	u8         reserved_at_0[0x60e0];
 };
-- 
1.8.3.1


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

* [PATCH net-next RFC 2/3] net/mlx5: Add functions to set/query MFRL register
  2020-01-14 15:55 [PATCH net-next RFC 0/3] Add mlx5 devices FW upgrade reset support Moshe Shemesh
  2020-01-14 15:55 ` [PATCH net-next RFC 1/3] net/mlx5: Add structure layout and defines for MFRL register Moshe Shemesh
@ 2020-01-14 15:55 ` " Moshe Shemesh
  2020-01-14 15:55 ` [PATCH net-next RFC 3/3] net/mlx5: Add FW upgrade reset support Moshe Shemesh
  2 siblings, 0 replies; 7+ messages in thread
From: Moshe Shemesh @ 2020-01-14 15:55 UTC (permalink / raw)
  To: David S. Miller; +Cc: Alexander Duyck, netdev, linux-kernel, Moshe Shemesh

Add functions to set the reset level required and to query the reset
levels supported by fw.

Signed-off-by: Moshe Shemesh <moshe@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx5/core/fw.c       | 44 ++++++++++++++++++++++
 .../net/ethernet/mellanox/mlx5/core/mlx5_core.h    |  2 +
 2 files changed, 46 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw.c b/drivers/net/ethernet/mellanox/mlx5/core/fw.c
index 1723229..1c6dfe9 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fw.c
@@ -769,3 +769,47 @@ int mlx5_fw_version_query(struct mlx5_core_dev *dev,
 
 	return 0;
 }
+
+static int mlx5_reg_mfrl_set(struct mlx5_core_dev *dev, u8 reset_level,
+			     u8 reset_type_sel)
+{
+	u32 out[MLX5_ST_SZ_DW(mfrl_reg)];
+	u32 in[MLX5_ST_SZ_DW(mfrl_reg)] = {};
+
+	MLX5_SET(mfrl_reg, in, reset_level, reset_level);
+	MLX5_SET(mfrl_reg, in, rst_type_sel, reset_type_sel);
+
+	return mlx5_core_access_reg(dev, in, sizeof(in), out,
+				    sizeof(out), MLX5_REG_MFRL, 0, 1);
+}
+
+static int mlx5_reg_mfrl_query(struct mlx5_core_dev *dev, u8 *reset_level,
+			       u8 *reset_type_sel, u8 *reset_type)
+{
+	u32 out[MLX5_ST_SZ_DW(mfrl_reg)] = {};
+	u32 in[MLX5_ST_SZ_DW(mfrl_reg)] = {};
+	int err;
+
+	err = mlx5_core_access_reg(dev, in, sizeof(in), out,
+				   sizeof(out), MLX5_REG_MFRL, 0, 0);
+	if (err)
+		return err;
+
+	*reset_level = MLX5_GET(mfrl_reg, out, reset_level);
+	*reset_type = MLX5_GET(mfrl_reg, out, reset_type);
+	*reset_type_sel = MLX5_GET(mfrl_reg, out, rst_type_sel);
+
+	return 0;
+}
+
+int mlx5_fw_query_reset_level(struct mlx5_core_dev *dev, u8 *reset_level)
+{
+	u8 reset_type_sel, reset_type;
+
+	return mlx5_reg_mfrl_query(dev, reset_level, &reset_type_sel, &reset_type);
+}
+
+int mlx5_fw_set_reset_level(struct mlx5_core_dev *dev, u8 reset_level)
+{
+	return mlx5_reg_mfrl_set(dev, reset_level, 0);
+}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
index da67b28..1b55a5a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
@@ -210,6 +210,8 @@ int mlx5_firmware_flash(struct mlx5_core_dev *dev, const struct firmware *fw,
 			struct netlink_ext_ack *extack);
 int mlx5_fw_version_query(struct mlx5_core_dev *dev,
 			  u32 *running_ver, u32 *stored_ver);
+int mlx5_fw_query_reset_level(struct mlx5_core_dev *dev, u8 *reset_level);
+int mlx5_fw_set_reset_level(struct mlx5_core_dev *dev, u8 reset_level);
 
 void mlx5e_init(void);
 void mlx5e_cleanup(void);
-- 
1.8.3.1


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

* [PATCH net-next RFC 3/3] net/mlx5: Add FW upgrade reset support
  2020-01-14 15:55 [PATCH net-next RFC 0/3] Add mlx5 devices FW upgrade reset support Moshe Shemesh
  2020-01-14 15:55 ` [PATCH net-next RFC 1/3] net/mlx5: Add structure layout and defines for MFRL register Moshe Shemesh
  2020-01-14 15:55 ` [PATCH net-next RFC 2/3] net/mlx5: Add functions to set/query " Moshe Shemesh
@ 2020-01-14 15:55 ` Moshe Shemesh
  2020-01-15 15:01   ` Jakub Kicinski
  2 siblings, 1 reply; 7+ messages in thread
From: Moshe Shemesh @ 2020-01-14 15:55 UTC (permalink / raw)
  To: David S. Miller; +Cc: Alexander Duyck, netdev, linux-kernel, Moshe Shemesh

Add support for FW upgrade reset.
On devlink reload the driver checks if there is a FW stored pending
upgrade reset. In such case the driver will set the device to FW upgrade
reset on next PCI link toggle and do link toggle after unload.

To do PCI link toggle, the driver ensures that no other device ID under
the same bridge by checking that all the PF functions under the same PCI
bridge have same device ID. If no other device it uses PCI bridge link
control to turn link down and up.

Signed-off-by: Moshe Shemesh <moshe@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx5/core/devlink.c | 81 ++++++++++++++++++++++-
 1 file changed, 80 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
index ac108f1..2aa9e99 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
@@ -85,12 +85,91 @@ static u16 mlx5_fw_ver_subminor(u32 version)
 	return 0;
 }
 
+static int mlx5_pci_link_toggle(struct mlx5_core_dev *dev)
+{
+	struct pci_bus *bridge_bus = dev->pdev->bus;
+	struct pci_dev *bridge = bridge_bus->self;
+	struct pci_dev *sdev;
+	u16 dev_id, sdev_id;
+	u16 reg16;
+	int cap;
+	int err;
+
+	/* Check that all functions under the pci bridge are VFs and PFs of
+	 * this device otherwise fail this function.
+	 */
+	pci_read_config_word(dev->pdev, PCI_DEVICE_ID, &dev_id);
+	list_for_each_entry(sdev, &bridge_bus->devices, bus_list) {
+		pci_read_config_word(sdev, PCI_DEVICE_ID, &sdev_id);
+		if (sdev_id != 0xFFFF && sdev_id != dev_id)
+			return -EPERM;
+	}
+
+	cap = pci_find_capability(bridge, PCI_CAP_ID_EXP);
+	if (!cap)
+		return -EOPNOTSUPP;
+
+	list_for_each_entry(sdev, &bridge_bus->devices, bus_list) {
+		pci_save_state(sdev);
+		pci_cfg_access_lock(sdev);
+	}
+	err = pci_read_config_word(bridge, cap + PCI_EXP_LNKCTL, &reg16);
+	if (err)
+		return err;
+	reg16 |= PCI_EXP_LNKCTL_LD;
+	err = pci_write_config_word(bridge, cap + PCI_EXP_LNKCTL, reg16);
+	if (err)
+		return err;
+	msleep(100);
+	reg16 &= ~PCI_EXP_LNKCTL_LD;
+	err = pci_write_config_word(bridge, cap + PCI_EXP_LNKCTL, reg16);
+	if (err)
+		return err;
+	msleep(100);
+	list_for_each_entry(sdev, &bridge_bus->devices, bus_list) {
+		pci_cfg_access_unlock(sdev);
+		pci_restore_state(sdev);
+	}
+
+	return 0;
+}
+
 static int mlx5_devlink_reload_down(struct devlink *devlink, bool netns_change,
 				    struct netlink_ext_ack *extack)
 {
 	struct mlx5_core_dev *dev = devlink_priv(devlink);
+	bool pci_link_toggle_required = false;
+	u32 running_fw, stored_fw;
+	u8 reset_level;
+	int err;
+
+	err = mlx5_fw_version_query(dev, &running_fw, &stored_fw);
+	if (err)
+		return err;
 
-	return mlx5_unload_one(dev, false);
+	if (stored_fw) {
+		err = mlx5_fw_query_reset_level(dev, &reset_level);
+		if (err)
+			return err;
+		if (reset_level & MLX5_MFRL_REG_RESET_LEVEL3) {
+			err = mlx5_fw_set_reset_level(dev,
+						      MLX5_MFRL_REG_RESET_LEVEL3);
+			if (err)
+				return err;
+			pci_link_toggle_required = true;
+		} else {
+			mlx5_core_warn(dev, "FW upgrade requires reboot\n");
+		}
+	}
+
+	err =  mlx5_unload_one(dev, false);
+	if (err)
+		return err;
+
+	if (pci_link_toggle_required)
+		return mlx5_pci_link_toggle(dev);
+
+	return 0;
 }
 
 static int mlx5_devlink_reload_up(struct devlink *devlink,
-- 
1.8.3.1


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

* Re: [PATCH net-next RFC 3/3] net/mlx5: Add FW upgrade reset support
  2020-01-14 15:55 ` [PATCH net-next RFC 3/3] net/mlx5: Add FW upgrade reset support Moshe Shemesh
@ 2020-01-15 15:01   ` Jakub Kicinski
  2020-01-16 14:52     ` Moshe Shemesh
  0 siblings, 1 reply; 7+ messages in thread
From: Jakub Kicinski @ 2020-01-15 15:01 UTC (permalink / raw)
  To: Moshe Shemesh; +Cc: David S. Miller, Alexander Duyck, netdev, linux-kernel

On Tue, 14 Jan 2020 17:55:28 +0200, Moshe Shemesh wrote:
> Add support for FW upgrade reset.
> On devlink reload the driver checks if there is a FW stored pending
> upgrade reset. In such case the driver will set the device to FW upgrade
> reset on next PCI link toggle and do link toggle after unload.
> 
> To do PCI link toggle, the driver ensures that no other device ID under
> the same bridge by checking that all the PF functions under the same PCI
> bridge have same device ID. If no other device it uses PCI bridge link
> control to turn link down and up.
> 
> Signed-off-by: Moshe Shemesh <moshe@mellanox.com>

I'd have a slight preference for the reset to be an explicit command
rather than something the driver does automatically on the reload if
there are pending changes. Won't there ever be scenarios where users
just want to hard reset the device for their own reason?

If multiple devices under one bridge are a real concern (or otherwise
interdependencies) would it make sense to mark the devices as "reload
pending" and perform the reloads once all devices in the group has this
mark set?

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

* Re: [PATCH net-next RFC 3/3] net/mlx5: Add FW upgrade reset support
  2020-01-15 15:01   ` Jakub Kicinski
@ 2020-01-16 14:52     ` Moshe Shemesh
  2020-01-17  1:26       ` Jakub Kicinski
  0 siblings, 1 reply; 7+ messages in thread
From: Moshe Shemesh @ 2020-01-16 14:52 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: David S. Miller, Alexander Duyck, netdev, linux-kernel


On 1/15/2020 5:01 PM, Jakub Kicinski wrote:
> On Tue, 14 Jan 2020 17:55:28 +0200, Moshe Shemesh wrote:
>> Add support for FW upgrade reset.
>> On devlink reload the driver checks if there is a FW stored pending
>> upgrade reset. In such case the driver will set the device to FW upgrade
>> reset on next PCI link toggle and do link toggle after unload.
>>
>> To do PCI link toggle, the driver ensures that no other device ID under
>> the same bridge by checking that all the PF functions under the same PCI
>> bridge have same device ID. If no other device it uses PCI bridge link
>> control to turn link down and up.
>>
>> Signed-off-by: Moshe Shemesh <moshe@mellanox.com>
> I'd have a slight preference for the reset to be an explicit command
> rather than something the driver does automatically on the reload if
> there are pending changes. Won't there ever be scenarios where users
> just want to hard reset the device for their own reason?


Good point, I will take it with Jiri, may add a new devlink dev command 
for that.

>
> If multiple devices under one bridge are a real concern (or otherwise
> interdependencies) would it make sense to mark the devices as "reload
> pending" and perform the reloads once all devices in the group has this
> mark set?

All mlx5 current devices support PCI - Express only.

PCI-Express device should have its own PCI-Express bridge, it is 1x1 
connection.

So the check here is just to verify, all functions found under the 
bridge are expected to be the same device functions (PFs and VFs).


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

* Re: [PATCH net-next RFC 3/3] net/mlx5: Add FW upgrade reset support
  2020-01-16 14:52     ` Moshe Shemesh
@ 2020-01-17  1:26       ` Jakub Kicinski
  0 siblings, 0 replies; 7+ messages in thread
From: Jakub Kicinski @ 2020-01-17  1:26 UTC (permalink / raw)
  To: Moshe Shemesh; +Cc: David S. Miller, Alexander Duyck, netdev, linux-kernel

On Thu, 16 Jan 2020 14:52:35 +0000, Moshe Shemesh wrote:
> > If multiple devices under one bridge are a real concern (or otherwise
> > interdependencies) would it make sense to mark the devices as "reload
> > pending" and perform the reloads once all devices in the group has this
> > mark set?  
> 
> All mlx5 current devices support PCI - Express only.
> 
> PCI-Express device should have its own PCI-Express bridge, it is 1x1 
> connection.
> 
> So the check here is just to verify, all functions found under the 
> bridge are expected to be the same device functions (PFs and VFs).

Ah, good, I couldn't confirm that PCIe fact with google fast enough :)
The check sounds good then, with perhaps a small suggestion to add 
a helper in PCIe core if it's already done by two drivers? Can be as 
a follow up..

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

end of thread, back to index

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-14 15:55 [PATCH net-next RFC 0/3] Add mlx5 devices FW upgrade reset support Moshe Shemesh
2020-01-14 15:55 ` [PATCH net-next RFC 1/3] net/mlx5: Add structure layout and defines for MFRL register Moshe Shemesh
2020-01-14 15:55 ` [PATCH net-next RFC 2/3] net/mlx5: Add functions to set/query " Moshe Shemesh
2020-01-14 15:55 ` [PATCH net-next RFC 3/3] net/mlx5: Add FW upgrade reset support Moshe Shemesh
2020-01-15 15:01   ` Jakub Kicinski
2020-01-16 14:52     ` Moshe Shemesh
2020-01-17  1:26       ` Jakub Kicinski

Netdev Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/netdev/0 netdev/git/0.git
	git clone --mirror https://lore.kernel.org/netdev/1 netdev/git/1.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 netdev netdev/ https://lore.kernel.org/netdev \
		netdev@vger.kernel.org
	public-inbox-index netdev

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.netdev


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git