linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Moshe Shemesh <moshe@mellanox.com>
To: "David S. Miller" <davem@davemloft.net>
Cc: Alexander Duyck <alexander.duyck@gmail.com>,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	Moshe Shemesh <moshe@mellanox.com>
Subject: [PATCH net-next RFC 3/3] net/mlx5: Add FW upgrade reset support
Date: Tue, 14 Jan 2020 17:55:28 +0200	[thread overview]
Message-ID: <1579017328-19643-4-git-send-email-moshe@mellanox.com> (raw)
In-Reply-To: <1579017328-19643-1-git-send-email-moshe@mellanox.com>

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


  parent reply	other threads:[~2020-01-14 15:55 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
2020-01-15 15:01   ` [PATCH net-next RFC 3/3] net/mlx5: Add FW upgrade reset support Jakub Kicinski
2020-01-16 14:52     ` Moshe Shemesh
2020-01-17  1:26       ` Jakub Kicinski
2020-01-18 19:57         ` Moshe Shemesh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1579017328-19643-4-git-send-email-moshe@mellanox.com \
    --to=moshe@mellanox.com \
    --cc=alexander.duyck@gmail.com \
    --cc=davem@davemloft.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).