All of lore.kernel.org
 help / color / mirror / Atom feed
* [patch net-next v3 0/8] expose flash update status to user
@ 2019-06-04 13:40 Jiri Pirko
  2019-06-04 13:40 ` [patch net-next v3 1/8] mlxsw: Move firmware flash implementation to devlink Jiri Pirko
                   ` (12 more replies)
  0 siblings, 13 replies; 24+ messages in thread
From: Jiri Pirko @ 2019-06-04 13:40 UTC (permalink / raw)
  To: netdev
  Cc: davem, mlxsw, jakub.kicinski, sthemmin, dsahern, saeedm, leon,
	f.fainelli

From: Jiri Pirko <jiri@mellanox.com>

When user is flashing device using devlink, he currenly does not see any
information about what is going on, percentages, etc.
Drivers, for example mlxsw and mlx5, have notion about the progress
and what is happening. This patchset exposes this progress
information to userspace.

Example output for existing flash command:
$ devlink dev flash pci/0000:01:00.0 file firmware.bin
Preparing to flash
Flashing 100%
Flashing done

See this console recording which shows flashing FW on a Mellanox
Spectrum device:
https://asciinema.org/a/247926

---
Please see individual patches for changelog.
v2->v3 only adds tags and the last selftest patch

Jiri Pirko (8):
  mlxsw: Move firmware flash implementation to devlink
  mlx5: Move firmware flash implementation to devlink
  mlxfw: Propagate error messages through extack
  devlink: allow driver to update progress of flash update
  mlxfw: Introduce status_notify op and call it to notify about the
    status
  mlxsw: Implement flash update status notifications
  netdevsim: implement fake flash updating with notifications
  selftests: add basic netdevsim devlink flash testing

 drivers/net/ethernet/mellanox/mlx5/core/en.h  |   2 -
 .../ethernet/mellanox/mlx5/core/en_ethtool.c  |  35 ------
 drivers/net/ethernet/mellanox/mlx5/core/fw.c  |   6 +-
 .../mellanox/mlx5/core/ipoib/ethtool.c        |   9 --
 .../net/ethernet/mellanox/mlx5/core/main.c    |  20 ++++
 .../ethernet/mellanox/mlx5/core/mlx5_core.h   |   3 +-
 drivers/net/ethernet/mellanox/mlxfw/mlxfw.h   |  11 +-
 .../net/ethernet/mellanox/mlxfw/mlxfw_fsm.c   |  57 ++++++++--
 drivers/net/ethernet/mellanox/mlxsw/core.c    |  15 +++
 drivers/net/ethernet/mellanox/mlxsw/core.h    |   3 +
 .../net/ethernet/mellanox/mlxsw/spectrum.c    |  75 +++++++------
 drivers/net/netdevsim/dev.c                   |  44 ++++++++
 drivers/net/netdevsim/netdevsim.h             |   1 +
 include/net/devlink.h                         |   8 ++
 include/uapi/linux/devlink.h                  |   5 +
 net/core/devlink.c                            | 102 ++++++++++++++++++
 .../drivers/net/netdevsim/devlink.sh          |  53 +++++++++
 17 files changed, 358 insertions(+), 91 deletions(-)
 create mode 100755 tools/testing/selftests/drivers/net/netdevsim/devlink.sh

-- 
2.17.2


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

* [patch net-next v3 1/8] mlxsw: Move firmware flash implementation to devlink
  2019-06-04 13:40 [patch net-next v3 0/8] expose flash update status to user Jiri Pirko
@ 2019-06-04 13:40 ` Jiri Pirko
  2019-06-04 13:40 ` [patch net-next v3 2/8] mlx5: " Jiri Pirko
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2019-06-04 13:40 UTC (permalink / raw)
  To: netdev
  Cc: davem, mlxsw, jakub.kicinski, sthemmin, dsahern, saeedm, leon,
	f.fainelli

From: Jiri Pirko <jiri@mellanox.com>

Benefit from the devlink flash update implementation and ethtool
fallback to it and move firmware flash implementation there.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/core.c    | 15 ++++++
 drivers/net/ethernet/mellanox/mlxsw/core.h    |  3 ++
 .../net/ethernet/mellanox/mlxsw/spectrum.c    | 49 +++++++++----------
 3 files changed, 41 insertions(+), 26 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
index 182762898361..1c4ef8ed1706 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
@@ -1003,6 +1003,20 @@ static int mlxsw_devlink_core_bus_device_reload(struct devlink *devlink,
 	return err;
 }
 
+static int mlxsw_devlink_flash_update(struct devlink *devlink,
+				      const char *file_name,
+				      const char *component,
+				      struct netlink_ext_ack *extack)
+{
+	struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
+	struct mlxsw_driver *mlxsw_driver = mlxsw_core->driver;
+
+	if (!mlxsw_driver->flash_update)
+		return -EOPNOTSUPP;
+	return mlxsw_driver->flash_update(mlxsw_core, file_name,
+					  component, extack);
+}
+
 static const struct devlink_ops mlxsw_devlink_ops = {
 	.reload				= mlxsw_devlink_core_bus_device_reload,
 	.port_type_set			= mlxsw_devlink_port_type_set,
@@ -1019,6 +1033,7 @@ static const struct devlink_ops mlxsw_devlink_ops = {
 	.sb_occ_port_pool_get		= mlxsw_devlink_sb_occ_port_pool_get,
 	.sb_occ_tc_port_bind_get	= mlxsw_devlink_sb_occ_tc_port_bind_get,
 	.info_get			= mlxsw_devlink_info_get,
+	.flash_update			= mlxsw_devlink_flash_update,
 };
 
 static int
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h
index e3832cb5bdda..a44ad0fb9477 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h
@@ -284,6 +284,9 @@ struct mlxsw_driver {
 				       unsigned int sb_index, u16 tc_index,
 				       enum devlink_sb_pool_type pool_type,
 				       u32 *p_cur, u32 *p_max);
+	int (*flash_update)(struct mlxsw_core *mlxsw_core,
+			    const char *file_name, const char *component,
+			    struct netlink_ext_ack *extack);
 	void (*txhdr_construct)(struct sk_buff *skb,
 				const struct mlxsw_tx_info *tx_info);
 	int (*resources_register)(struct mlxsw_core *mlxsw_core);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index dfe6b44baf63..6f9ca943f50d 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -388,6 +388,27 @@ static int mlxsw_sp_fw_rev_validate(struct mlxsw_sp *mlxsw_sp)
 		return 0;
 }
 
+static int mlxsw_sp_flash_update(struct mlxsw_core *mlxsw_core,
+				 const char *file_name, const char *component,
+				 struct netlink_ext_ack *extack)
+{
+	struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
+	const struct firmware *firmware;
+	int err;
+
+	if (component)
+		return -EOPNOTSUPP;
+
+	err = request_firmware_direct(&firmware, file_name,
+				      mlxsw_sp->bus_info->dev);
+	if (err)
+		return err;
+	err = mlxsw_sp_firmware_flash(mlxsw_sp, firmware);
+	release_firmware(firmware);
+
+	return err;
+}
+
 int mlxsw_sp_flow_counter_get(struct mlxsw_sp *mlxsw_sp,
 			      unsigned int counter_index, u64 *packets,
 			      u64 *bytes)
@@ -3159,31 +3180,6 @@ mlxsw_sp_port_set_link_ksettings(struct net_device *dev,
 	return 0;
 }
 
-static int mlxsw_sp_flash_device(struct net_device *dev,
-				 struct ethtool_flash *flash)
-{
-	struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
-	struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
-	const struct firmware *firmware;
-	int err;
-
-	if (flash->region != ETHTOOL_FLASH_ALL_REGIONS)
-		return -EOPNOTSUPP;
-
-	dev_hold(dev);
-	rtnl_unlock();
-
-	err = request_firmware_direct(&firmware, flash->data, &dev->dev);
-	if (err)
-		goto out;
-	err = mlxsw_sp_firmware_flash(mlxsw_sp, firmware);
-	release_firmware(firmware);
-out:
-	rtnl_lock();
-	dev_put(dev);
-	return err;
-}
-
 static int mlxsw_sp_get_module_info(struct net_device *netdev,
 				    struct ethtool_modinfo *modinfo)
 {
@@ -3224,7 +3220,6 @@ static const struct ethtool_ops mlxsw_sp_port_ethtool_ops = {
 	.get_sset_count		= mlxsw_sp_port_get_sset_count,
 	.get_link_ksettings	= mlxsw_sp_port_get_link_ksettings,
 	.set_link_ksettings	= mlxsw_sp_port_set_link_ksettings,
-	.flash_device		= mlxsw_sp_flash_device,
 	.get_module_info	= mlxsw_sp_get_module_info,
 	.get_module_eeprom	= mlxsw_sp_get_module_eeprom,
 };
@@ -4889,6 +4884,7 @@ static struct mlxsw_driver mlxsw_sp1_driver = {
 	.sb_occ_max_clear		= mlxsw_sp_sb_occ_max_clear,
 	.sb_occ_port_pool_get		= mlxsw_sp_sb_occ_port_pool_get,
 	.sb_occ_tc_port_bind_get	= mlxsw_sp_sb_occ_tc_port_bind_get,
+	.flash_update			= mlxsw_sp_flash_update,
 	.txhdr_construct		= mlxsw_sp_txhdr_construct,
 	.resources_register		= mlxsw_sp1_resources_register,
 	.kvd_sizes_get			= mlxsw_sp_kvd_sizes_get,
@@ -4917,6 +4913,7 @@ static struct mlxsw_driver mlxsw_sp2_driver = {
 	.sb_occ_max_clear		= mlxsw_sp_sb_occ_max_clear,
 	.sb_occ_port_pool_get		= mlxsw_sp_sb_occ_port_pool_get,
 	.sb_occ_tc_port_bind_get	= mlxsw_sp_sb_occ_tc_port_bind_get,
+	.flash_update			= mlxsw_sp_flash_update,
 	.txhdr_construct		= mlxsw_sp_txhdr_construct,
 	.resources_register		= mlxsw_sp2_resources_register,
 	.params_register		= mlxsw_sp2_params_register,
-- 
2.17.2


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

* [patch net-next v3 2/8] mlx5: Move firmware flash implementation to devlink
  2019-06-04 13:40 [patch net-next v3 0/8] expose flash update status to user Jiri Pirko
  2019-06-04 13:40 ` [patch net-next v3 1/8] mlxsw: Move firmware flash implementation to devlink Jiri Pirko
@ 2019-06-04 13:40 ` Jiri Pirko
  2019-06-04 18:40   ` Saeed Mahameed
  2019-06-04 13:40 ` [patch net-next v3 3/8] mlxfw: Propagate error messages through extack Jiri Pirko
                   ` (10 subsequent siblings)
  12 siblings, 1 reply; 24+ messages in thread
From: Jiri Pirko @ 2019-06-04 13:40 UTC (permalink / raw)
  To: netdev
  Cc: davem, mlxsw, jakub.kicinski, sthemmin, dsahern, saeedm, leon,
	f.fainelli

From: Jiri Pirko <jiri@mellanox.com>

Benefit from the devlink flash update implementation and ethtool
fallback to it and move firmware flash implementation there.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx5/core/en.h  |  2 --
 .../ethernet/mellanox/mlx5/core/en_ethtool.c  | 35 -------------------
 .../mellanox/mlx5/core/ipoib/ethtool.c        |  9 -----
 .../net/ethernet/mellanox/mlx5/core/main.c    | 20 +++++++++++
 4 files changed, 20 insertions(+), 46 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 3a183d690e23..4e417dfe4ee5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -1074,8 +1074,6 @@ u32 mlx5e_ethtool_get_rxfh_key_size(struct mlx5e_priv *priv);
 u32 mlx5e_ethtool_get_rxfh_indir_size(struct mlx5e_priv *priv);
 int mlx5e_ethtool_get_ts_info(struct mlx5e_priv *priv,
 			      struct ethtool_ts_info *info);
-int mlx5e_ethtool_flash_device(struct mlx5e_priv *priv,
-			       struct ethtool_flash *flash);
 void mlx5e_ethtool_get_pauseparam(struct mlx5e_priv *priv,
 				  struct ethtool_pauseparam *pauseparam);
 int mlx5e_ethtool_set_pauseparam(struct mlx5e_priv *priv,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
index dd764e0471f2..ea59097dd4f8 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -1867,40 +1867,6 @@ static u32 mlx5e_get_priv_flags(struct net_device *netdev)
 	return priv->channels.params.pflags;
 }
 
-int mlx5e_ethtool_flash_device(struct mlx5e_priv *priv,
-			       struct ethtool_flash *flash)
-{
-	struct mlx5_core_dev *mdev = priv->mdev;
-	struct net_device *dev = priv->netdev;
-	const struct firmware *fw;
-	int err;
-
-	if (flash->region != ETHTOOL_FLASH_ALL_REGIONS)
-		return -EOPNOTSUPP;
-
-	err = request_firmware_direct(&fw, flash->data, &dev->dev);
-	if (err)
-		return err;
-
-	dev_hold(dev);
-	rtnl_unlock();
-
-	err = mlx5_firmware_flash(mdev, fw);
-	release_firmware(fw);
-
-	rtnl_lock();
-	dev_put(dev);
-	return err;
-}
-
-static int mlx5e_flash_device(struct net_device *dev,
-			      struct ethtool_flash *flash)
-{
-	struct mlx5e_priv *priv = netdev_priv(dev);
-
-	return mlx5e_ethtool_flash_device(priv, flash);
-}
-
 #ifndef CONFIG_MLX5_EN_RXNFC
 /* When CONFIG_MLX5_EN_RXNFC=n we only support ETHTOOL_GRXRINGS
  * otherwise this function will be defined from en_fs_ethtool.c
@@ -1939,7 +1905,6 @@ const struct ethtool_ops mlx5e_ethtool_ops = {
 #ifdef CONFIG_MLX5_EN_RXNFC
 	.set_rxnfc         = mlx5e_set_rxnfc,
 #endif
-	.flash_device      = mlx5e_flash_device,
 	.get_tunable       = mlx5e_get_tunable,
 	.set_tunable       = mlx5e_set_tunable,
 	.get_pauseparam    = mlx5e_get_pauseparam,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c
index 90cb50fe17fd..ebd81f6b556e 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ethtool.c
@@ -122,14 +122,6 @@ static int mlx5i_get_ts_info(struct net_device *netdev,
 	return mlx5e_ethtool_get_ts_info(priv, info);
 }
 
-static int mlx5i_flash_device(struct net_device *netdev,
-			      struct ethtool_flash *flash)
-{
-	struct mlx5e_priv *priv = mlx5i_epriv(netdev);
-
-	return mlx5e_ethtool_flash_device(priv, flash);
-}
-
 enum mlx5_ptys_width {
 	MLX5_PTYS_WIDTH_1X	= 1 << 0,
 	MLX5_PTYS_WIDTH_2X	= 1 << 1,
@@ -241,7 +233,6 @@ const struct ethtool_ops mlx5i_ethtool_ops = {
 	.get_ethtool_stats  = mlx5i_get_ethtool_stats,
 	.get_ringparam      = mlx5i_get_ringparam,
 	.set_ringparam      = mlx5i_set_ringparam,
-	.flash_device       = mlx5i_flash_device,
 	.get_channels       = mlx5i_get_channels,
 	.set_channels       = mlx5i_set_channels,
 	.get_coalesce       = mlx5i_get_coalesce,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
index b27f9537256c..2fc2162901de 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -1214,6 +1214,25 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, bool cleanup)
 	return err;
 }
 
+static int mlx5_devlink_flash_update(struct devlink *devlink,
+				     const char *file_name,
+				     const char *component,
+				     struct netlink_ext_ack *extack)
+{
+	struct mlx5_core_dev *dev = devlink_priv(devlink);
+	const struct firmware *fw;
+	int err;
+
+	if (component)
+		return -EOPNOTSUPP;
+
+	err = request_firmware_direct(&fw, file_name, &dev->pdev->dev);
+	if (err)
+		return err;
+
+	return mlx5_firmware_flash(dev, fw);
+}
+
 static const struct devlink_ops mlx5_devlink_ops = {
 #ifdef CONFIG_MLX5_ESWITCH
 	.eswitch_mode_set = mlx5_devlink_eswitch_mode_set,
@@ -1223,6 +1242,7 @@ static const struct devlink_ops mlx5_devlink_ops = {
 	.eswitch_encap_mode_set = mlx5_devlink_eswitch_encap_mode_set,
 	.eswitch_encap_mode_get = mlx5_devlink_eswitch_encap_mode_get,
 #endif
+	.flash_update = mlx5_devlink_flash_update,
 };
 
 static int mlx5_mdev_init(struct mlx5_core_dev *dev, int profile_idx)
-- 
2.17.2


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

* [patch net-next v3 3/8] mlxfw: Propagate error messages through extack
  2019-06-04 13:40 [patch net-next v3 0/8] expose flash update status to user Jiri Pirko
  2019-06-04 13:40 ` [patch net-next v3 1/8] mlxsw: Move firmware flash implementation to devlink Jiri Pirko
  2019-06-04 13:40 ` [patch net-next v3 2/8] mlx5: " Jiri Pirko
@ 2019-06-04 13:40 ` Jiri Pirko
  2019-06-04 13:40 ` [patch net-next v3 4/8] devlink: allow driver to update progress of flash update Jiri Pirko
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2019-06-04 13:40 UTC (permalink / raw)
  To: netdev
  Cc: davem, mlxsw, jakub.kicinski, sthemmin, dsahern, saeedm, leon,
	f.fainelli

From: Jiri Pirko <jiri@mellanox.com>

Currently the error messages are printed to dmesg. Propagate them also
to directly to user doing the flashing through extack.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
---
v1->v2:
- dropped "is which" from errmsg.
---
 drivers/net/ethernet/mellanox/mlx5/core/fw.c  |  6 ++--
 .../net/ethernet/mellanox/mlx5/core/main.c    |  2 +-
 .../ethernet/mellanox/mlx5/core/mlx5_core.h   |  3 +-
 drivers/net/ethernet/mellanox/mlxfw/mlxfw.h   |  7 ++--
 .../net/ethernet/mellanox/mlxfw/mlxfw_fsm.c   | 33 +++++++++++++------
 .../net/ethernet/mellanox/mlxsw/spectrum.c    | 10 +++---
 6 files changed, 41 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw.c b/drivers/net/ethernet/mellanox/mlx5/core/fw.c
index 1ab6f7e3bec6..e8fedb307b2c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fw.c
@@ -552,7 +552,8 @@ static const struct mlxfw_dev_ops mlx5_mlxfw_dev_ops = {
 };
 
 int mlx5_firmware_flash(struct mlx5_core_dev *dev,
-			const struct firmware *firmware)
+			const struct firmware *firmware,
+			struct netlink_ext_ack *extack)
 {
 	struct mlx5_mlxfw_dev mlx5_mlxfw_dev = {
 		.mlxfw_dev = {
@@ -571,5 +572,6 @@ int mlx5_firmware_flash(struct mlx5_core_dev *dev,
 		return -EOPNOTSUPP;
 	}
 
-	return mlxfw_firmware_flash(&mlx5_mlxfw_dev.mlxfw_dev, firmware);
+	return mlxfw_firmware_flash(&mlx5_mlxfw_dev.mlxfw_dev,
+				    firmware, extack);
 }
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
index 2fc2162901de..7ec135eaabc6 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -1230,7 +1230,7 @@ static int mlx5_devlink_flash_update(struct devlink *devlink,
 	if (err)
 		return err;
 
-	return mlx5_firmware_flash(dev, fw);
+	return mlx5_firmware_flash(dev, fw, extack);
 }
 
 static const struct devlink_ops mlx5_devlink_ops = {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
index 22e69d4813e4..d4dd8c1ae55c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
@@ -184,7 +184,8 @@ int mlx5_set_mtppse(struct mlx5_core_dev *mdev, u8 pin, u8 arm, u8 mode);
 			    MLX5_CAP_MCAM_FEATURE((mdev), mtpps_fs) &&	\
 			    MLX5_CAP_MCAM_FEATURE((mdev), mtpps_enh_out_per_adj))
 
-int mlx5_firmware_flash(struct mlx5_core_dev *dev, const struct firmware *fw);
+int mlx5_firmware_flash(struct mlx5_core_dev *dev, const struct firmware *fw,
+			struct netlink_ext_ack *extack);
 
 void mlx5e_init(void);
 void mlx5e_cleanup(void);
diff --git a/drivers/net/ethernet/mellanox/mlxfw/mlxfw.h b/drivers/net/ethernet/mellanox/mlxfw/mlxfw.h
index 14c0c62f8e73..83286b90593f 100644
--- a/drivers/net/ethernet/mellanox/mlxfw/mlxfw.h
+++ b/drivers/net/ethernet/mellanox/mlxfw/mlxfw.h
@@ -5,6 +5,7 @@
 #define _MLXFW_H
 
 #include <linux/firmware.h>
+#include <linux/netlink.h>
 
 enum mlxfw_fsm_state {
 	MLXFW_FSM_STATE_IDLE,
@@ -67,11 +68,13 @@ struct mlxfw_dev {
 
 #if IS_REACHABLE(CONFIG_MLXFW)
 int mlxfw_firmware_flash(struct mlxfw_dev *mlxfw_dev,
-			 const struct firmware *firmware);
+			 const struct firmware *firmware,
+			 struct netlink_ext_ack *extack);
 #else
 static inline
 int mlxfw_firmware_flash(struct mlxfw_dev *mlxfw_dev,
-			 const struct firmware *firmware)
+			 const struct firmware *firmware,
+			 struct netlink_ext_ack *extack)
 {
 	return -EOPNOTSUPP;
 }
diff --git a/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c b/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c
index 240c027e5f07..61c32c43a309 100644
--- a/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c
+++ b/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c
@@ -40,7 +40,8 @@ static const char * const mlxfw_fsm_state_err_str[] = {
 };
 
 static int mlxfw_fsm_state_wait(struct mlxfw_dev *mlxfw_dev, u32 fwhandle,
-				enum mlxfw_fsm_state fsm_state)
+				enum mlxfw_fsm_state fsm_state,
+				struct netlink_ext_ack *extack)
 {
 	enum mlxfw_fsm_state_err fsm_state_err;
 	enum mlxfw_fsm_state curr_fsm_state;
@@ -57,11 +58,13 @@ static int mlxfw_fsm_state_wait(struct mlxfw_dev *mlxfw_dev, u32 fwhandle,
 	if (fsm_state_err != MLXFW_FSM_STATE_ERR_OK) {
 		pr_err("Firmware flash failed: %s\n",
 		       mlxfw_fsm_state_err_str[fsm_state_err]);
+		NL_SET_ERR_MSG_MOD(extack, "Firmware flash failed");
 		return -EINVAL;
 	}
 	if (curr_fsm_state != fsm_state) {
 		if (--times == 0) {
 			pr_err("Timeout reached on FSM state change");
+			NL_SET_ERR_MSG_MOD(extack, "Timeout reached on FSM state change");
 			return -ETIMEDOUT;
 		}
 		msleep(MLXFW_FSM_STATE_WAIT_CYCLE_MS);
@@ -76,7 +79,8 @@ static int mlxfw_fsm_state_wait(struct mlxfw_dev *mlxfw_dev, u32 fwhandle,
 
 static int mlxfw_flash_component(struct mlxfw_dev *mlxfw_dev,
 				 u32 fwhandle,
-				 struct mlxfw_mfa2_component *comp)
+				 struct mlxfw_mfa2_component *comp,
+				 struct netlink_ext_ack *extack)
 {
 	u16 comp_max_write_size;
 	u8 comp_align_bits;
@@ -96,6 +100,7 @@ static int mlxfw_flash_component(struct mlxfw_dev *mlxfw_dev,
 	if (comp->data_size > comp_max_size) {
 		pr_err("Component %d is of size %d which is bigger than limit %d\n",
 		       comp->index, comp->data_size, comp_max_size);
+		NL_SET_ERR_MSG_MOD(extack, "Component is bigger than limit");
 		return -EINVAL;
 	}
 
@@ -110,7 +115,7 @@ static int mlxfw_flash_component(struct mlxfw_dev *mlxfw_dev,
 		return err;
 
 	err = mlxfw_fsm_state_wait(mlxfw_dev, fwhandle,
-				   MLXFW_FSM_STATE_DOWNLOAD);
+				   MLXFW_FSM_STATE_DOWNLOAD, extack);
 	if (err)
 		goto err_out;
 
@@ -134,7 +139,8 @@ static int mlxfw_flash_component(struct mlxfw_dev *mlxfw_dev,
 	if (err)
 		goto err_out;
 
-	err = mlxfw_fsm_state_wait(mlxfw_dev, fwhandle, MLXFW_FSM_STATE_LOCKED);
+	err = mlxfw_fsm_state_wait(mlxfw_dev, fwhandle,
+				   MLXFW_FSM_STATE_LOCKED, extack);
 	if (err)
 		goto err_out;
 	return 0;
@@ -145,7 +151,8 @@ static int mlxfw_flash_component(struct mlxfw_dev *mlxfw_dev,
 }
 
 static int mlxfw_flash_components(struct mlxfw_dev *mlxfw_dev, u32 fwhandle,
-				  struct mlxfw_mfa2_file *mfa2_file)
+				  struct mlxfw_mfa2_file *mfa2_file,
+				  struct netlink_ext_ack *extack)
 {
 	u32 component_count;
 	int err;
@@ -156,6 +163,7 @@ static int mlxfw_flash_components(struct mlxfw_dev *mlxfw_dev, u32 fwhandle,
 					      &component_count);
 	if (err) {
 		pr_err("Could not find device PSID in MFA2 file\n");
+		NL_SET_ERR_MSG_MOD(extack, "Could not find device PSID in MFA2 file");
 		return err;
 	}
 
@@ -168,7 +176,7 @@ static int mlxfw_flash_components(struct mlxfw_dev *mlxfw_dev, u32 fwhandle,
 			return PTR_ERR(comp);
 
 		pr_info("Flashing component type %d\n", comp->index);
-		err = mlxfw_flash_component(mlxfw_dev, fwhandle, comp);
+		err = mlxfw_flash_component(mlxfw_dev, fwhandle, comp, extack);
 		mlxfw_mfa2_file_component_put(comp);
 		if (err)
 			return err;
@@ -177,7 +185,8 @@ static int mlxfw_flash_components(struct mlxfw_dev *mlxfw_dev, u32 fwhandle,
 }
 
 int mlxfw_firmware_flash(struct mlxfw_dev *mlxfw_dev,
-			 const struct firmware *firmware)
+			 const struct firmware *firmware,
+			 struct netlink_ext_ack *extack)
 {
 	struct mlxfw_mfa2_file *mfa2_file;
 	u32 fwhandle;
@@ -185,6 +194,7 @@ int mlxfw_firmware_flash(struct mlxfw_dev *mlxfw_dev,
 
 	if (!mlxfw_mfa2_check(firmware)) {
 		pr_err("Firmware file is not MFA2\n");
+		NL_SET_ERR_MSG_MOD(extack, "Firmware file is not MFA2");
 		return -EINVAL;
 	}
 
@@ -196,15 +206,16 @@ int mlxfw_firmware_flash(struct mlxfw_dev *mlxfw_dev,
 	err = mlxfw_dev->ops->fsm_lock(mlxfw_dev, &fwhandle);
 	if (err) {
 		pr_err("Could not lock the firmware FSM\n");
+		NL_SET_ERR_MSG_MOD(extack, "Could not lock the firmware FSM");
 		goto err_fsm_lock;
 	}
 
 	err = mlxfw_fsm_state_wait(mlxfw_dev, fwhandle,
-				   MLXFW_FSM_STATE_LOCKED);
+				   MLXFW_FSM_STATE_LOCKED, extack);
 	if (err)
 		goto err_state_wait_idle_to_locked;
 
-	err = mlxfw_flash_components(mlxfw_dev, fwhandle, mfa2_file);
+	err = mlxfw_flash_components(mlxfw_dev, fwhandle, mfa2_file, extack);
 	if (err)
 		goto err_flash_components;
 
@@ -212,10 +223,12 @@ int mlxfw_firmware_flash(struct mlxfw_dev *mlxfw_dev,
 	err = mlxfw_dev->ops->fsm_activate(mlxfw_dev, fwhandle);
 	if (err) {
 		pr_err("Could not activate the downloaded image\n");
+		NL_SET_ERR_MSG_MOD(extack, "Could not activate the downloaded image");
 		goto err_fsm_activate;
 	}
 
-	err = mlxfw_fsm_state_wait(mlxfw_dev, fwhandle, MLXFW_FSM_STATE_LOCKED);
+	err = mlxfw_fsm_state_wait(mlxfw_dev, fwhandle,
+				   MLXFW_FSM_STATE_LOCKED, extack);
 	if (err)
 		goto err_state_wait_activate_to_locked;
 
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 6f9ca943f50d..2cba678863bd 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -307,7 +307,8 @@ static const struct mlxfw_dev_ops mlxsw_sp_mlxfw_dev_ops = {
 };
 
 static int mlxsw_sp_firmware_flash(struct mlxsw_sp *mlxsw_sp,
-				   const struct firmware *firmware)
+				   const struct firmware *firmware,
+				   struct netlink_ext_ack *extack)
 {
 	struct mlxsw_sp_mlxfw_dev mlxsw_sp_mlxfw_dev = {
 		.mlxfw_dev = {
@@ -320,7 +321,8 @@ static int mlxsw_sp_firmware_flash(struct mlxsw_sp *mlxsw_sp,
 	int err;
 
 	mlxsw_core_fw_flash_start(mlxsw_sp->core);
-	err = mlxfw_firmware_flash(&mlxsw_sp_mlxfw_dev.mlxfw_dev, firmware);
+	err = mlxfw_firmware_flash(&mlxsw_sp_mlxfw_dev.mlxfw_dev,
+				   firmware, extack);
 	mlxsw_core_fw_flash_end(mlxsw_sp->core);
 
 	return err;
@@ -374,7 +376,7 @@ static int mlxsw_sp_fw_rev_validate(struct mlxsw_sp *mlxsw_sp)
 		return err;
 	}
 
-	err = mlxsw_sp_firmware_flash(mlxsw_sp, firmware);
+	err = mlxsw_sp_firmware_flash(mlxsw_sp, firmware, NULL);
 	release_firmware(firmware);
 	if (err)
 		dev_err(mlxsw_sp->bus_info->dev, "Could not upgrade firmware\n");
@@ -403,7 +405,7 @@ static int mlxsw_sp_flash_update(struct mlxsw_core *mlxsw_core,
 				      mlxsw_sp->bus_info->dev);
 	if (err)
 		return err;
-	err = mlxsw_sp_firmware_flash(mlxsw_sp, firmware);
+	err = mlxsw_sp_firmware_flash(mlxsw_sp, firmware, extack);
 	release_firmware(firmware);
 
 	return err;
-- 
2.17.2


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

* [patch net-next v3 4/8] devlink: allow driver to update progress of flash update
  2019-06-04 13:40 [patch net-next v3 0/8] expose flash update status to user Jiri Pirko
                   ` (2 preceding siblings ...)
  2019-06-04 13:40 ` [patch net-next v3 3/8] mlxfw: Propagate error messages through extack Jiri Pirko
@ 2019-06-04 13:40 ` Jiri Pirko
  2019-06-04 13:40 ` [patch net-next v3 5/8] mlxfw: Introduce status_notify op and call it to notify about the status Jiri Pirko
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2019-06-04 13:40 UTC (permalink / raw)
  To: netdev
  Cc: davem, mlxsw, jakub.kicinski, sthemmin, dsahern, saeedm, leon,
	f.fainelli

From: Jiri Pirko <jiri@mellanox.com>

Introduce a function to be called from drivers during flash. It sends
notification to userspace about flash update progress.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
---
 include/net/devlink.h        |   8 +++
 include/uapi/linux/devlink.h |   5 ++
 net/core/devlink.c           | 102 +++++++++++++++++++++++++++++++++++
 3 files changed, 115 insertions(+)

diff --git a/include/net/devlink.h b/include/net/devlink.h
index 151eb930d329..8f65356132be 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -741,6 +741,14 @@ void
 devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,
 				     enum devlink_health_reporter_state state);
 
+void devlink_flash_update_begin_notify(struct devlink *devlink);
+void devlink_flash_update_end_notify(struct devlink *devlink);
+void devlink_flash_update_status_notify(struct devlink *devlink,
+					const char *status_msg,
+					const char *component,
+					unsigned long done,
+					unsigned long total);
+
 #if IS_ENABLED(CONFIG_NET_DEVLINK)
 
 void devlink_compat_running_version(struct net_device *dev,
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index 5bb4ea67d84f..5287b42c181f 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -104,6 +104,8 @@ enum devlink_command {
 	DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR,
 
 	DEVLINK_CMD_FLASH_UPDATE,
+	DEVLINK_CMD_FLASH_UPDATE_END,		/* notification only */
+	DEVLINK_CMD_FLASH_UPDATE_STATUS,	/* notification only */
 
 	/* add new commands above here */
 	__DEVLINK_CMD_MAX,
@@ -331,6 +333,9 @@ enum devlink_attr {
 
 	DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME,	/* string */
 	DEVLINK_ATTR_FLASH_UPDATE_COMPONENT,	/* string */
+	DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG,	/* string */
+	DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE,	/* u64 */
+	DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL,	/* u64 */
 
 	/* add new attributes above here, update the policy in devlink.c */
 
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 9716a7f382cb..963178d32dda 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -2673,6 +2673,108 @@ static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
 	return devlink->ops->reload(devlink, info->extack);
 }
 
+static int devlink_nl_flash_update_fill(struct sk_buff *msg,
+					struct devlink *devlink,
+					enum devlink_command cmd,
+					const char *status_msg,
+					const char *component,
+					unsigned long done, unsigned long total)
+{
+	void *hdr;
+
+	hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd);
+	if (!hdr)
+		return -EMSGSIZE;
+
+	if (devlink_nl_put_handle(msg, devlink))
+		goto nla_put_failure;
+
+	if (cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS)
+		goto out;
+
+	if (status_msg &&
+	    nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG,
+			   status_msg))
+		goto nla_put_failure;
+	if (component &&
+	    nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT,
+			   component))
+		goto nla_put_failure;
+	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE,
+			      done, DEVLINK_ATTR_PAD))
+		goto nla_put_failure;
+	if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL,
+			      total, DEVLINK_ATTR_PAD))
+		goto nla_put_failure;
+
+out:
+	genlmsg_end(msg, hdr);
+	return 0;
+
+nla_put_failure:
+	genlmsg_cancel(msg, hdr);
+	return -EMSGSIZE;
+}
+
+static void __devlink_flash_update_notify(struct devlink *devlink,
+					  enum devlink_command cmd,
+					  const char *status_msg,
+					  const char *component,
+					  unsigned long done,
+					  unsigned long total)
+{
+	struct sk_buff *msg;
+	int err;
+
+	WARN_ON(cmd != DEVLINK_CMD_FLASH_UPDATE &&
+		cmd != DEVLINK_CMD_FLASH_UPDATE_END &&
+		cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS);
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!msg)
+		return;
+
+	err = devlink_nl_flash_update_fill(msg, devlink, cmd, status_msg,
+					   component, done, total);
+	if (err)
+		goto out_free_msg;
+
+	genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
+				msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
+	return;
+
+out_free_msg:
+	nlmsg_free(msg);
+}
+
+void devlink_flash_update_begin_notify(struct devlink *devlink)
+{
+	__devlink_flash_update_notify(devlink,
+				      DEVLINK_CMD_FLASH_UPDATE,
+				      NULL, NULL, 0, 0);
+}
+EXPORT_SYMBOL_GPL(devlink_flash_update_begin_notify);
+
+void devlink_flash_update_end_notify(struct devlink *devlink)
+{
+	__devlink_flash_update_notify(devlink,
+				      DEVLINK_CMD_FLASH_UPDATE_END,
+				      NULL, NULL, 0, 0);
+}
+EXPORT_SYMBOL_GPL(devlink_flash_update_end_notify);
+
+void devlink_flash_update_status_notify(struct devlink *devlink,
+					const char *status_msg,
+					const char *component,
+					unsigned long done,
+					unsigned long total)
+{
+	__devlink_flash_update_notify(devlink,
+				      DEVLINK_CMD_FLASH_UPDATE_STATUS,
+				      status_msg, component, done, total);
+}
+EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify);
+
 static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
 				       struct genl_info *info)
 {
-- 
2.17.2


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

* [patch net-next v3 5/8] mlxfw: Introduce status_notify op and call it to notify about the status
  2019-06-04 13:40 [patch net-next v3 0/8] expose flash update status to user Jiri Pirko
                   ` (3 preceding siblings ...)
  2019-06-04 13:40 ` [patch net-next v3 4/8] devlink: allow driver to update progress of flash update Jiri Pirko
@ 2019-06-04 13:40 ` Jiri Pirko
  2019-06-04 13:40 ` [patch net-next v3 6/8] mlxsw: Implement flash update status notifications Jiri Pirko
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2019-06-04 13:40 UTC (permalink / raw)
  To: netdev
  Cc: davem, mlxsw, jakub.kicinski, sthemmin, dsahern, saeedm, leon,
	f.fainelli

From: Jiri Pirko <jiri@mellanox.com>

Add new op status_notify which is called to update the user about
flashing status.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxfw/mlxfw.h   |  4 ++++
 .../net/ethernet/mellanox/mlxfw/mlxfw_fsm.c   | 24 +++++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlxfw/mlxfw.h b/drivers/net/ethernet/mellanox/mlxfw/mlxfw.h
index 83286b90593f..c50e74ab02c4 100644
--- a/drivers/net/ethernet/mellanox/mlxfw/mlxfw.h
+++ b/drivers/net/ethernet/mellanox/mlxfw/mlxfw.h
@@ -58,6 +58,10 @@ struct mlxfw_dev_ops {
 	void (*fsm_cancel)(struct mlxfw_dev *mlxfw_dev, u32 fwhandle);
 
 	void (*fsm_release)(struct mlxfw_dev *mlxfw_dev, u32 fwhandle);
+
+	void (*status_notify)(struct mlxfw_dev *mlxfw_dev,
+			      const char *msg, const char *comp_name,
+			      u32 done_bytes, u32 total_bytes);
 };
 
 struct mlxfw_dev {
diff --git a/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c b/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c
index 61c32c43a309..67990406cba2 100644
--- a/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c
+++ b/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c
@@ -39,6 +39,16 @@ static const char * const mlxfw_fsm_state_err_str[] = {
 		"unknown error"
 };
 
+static void mlxfw_status_notify(struct mlxfw_dev *mlxfw_dev,
+				const char *msg, const char *comp_name,
+				u32 done_bytes, u32 total_bytes)
+{
+	if (!mlxfw_dev->ops->status_notify)
+		return;
+	mlxfw_dev->ops->status_notify(mlxfw_dev, msg, comp_name,
+				      done_bytes, total_bytes);
+}
+
 static int mlxfw_fsm_state_wait(struct mlxfw_dev *mlxfw_dev, u32 fwhandle,
 				enum mlxfw_fsm_state fsm_state,
 				struct netlink_ext_ack *extack)
@@ -85,11 +95,14 @@ static int mlxfw_flash_component(struct mlxfw_dev *mlxfw_dev,
 	u16 comp_max_write_size;
 	u8 comp_align_bits;
 	u32 comp_max_size;
+	char comp_name[8];
 	u16 block_size;
 	u8 *block_ptr;
 	u32 offset;
 	int err;
 
+	sprintf(comp_name, "%u", comp->index);
+
 	err = mlxfw_dev->ops->component_query(mlxfw_dev, comp->index,
 					      &comp_max_size, &comp_align_bits,
 					      &comp_max_write_size);
@@ -108,6 +121,7 @@ static int mlxfw_flash_component(struct mlxfw_dev *mlxfw_dev,
 					       comp_align_bits);
 
 	pr_debug("Component update\n");
+	mlxfw_status_notify(mlxfw_dev, "Updating component", comp_name, 0, 0);
 	err = mlxfw_dev->ops->fsm_component_update(mlxfw_dev, fwhandle,
 						   comp->index,
 						   comp->data_size);
@@ -120,6 +134,8 @@ static int mlxfw_flash_component(struct mlxfw_dev *mlxfw_dev,
 		goto err_out;
 
 	pr_debug("Component download\n");
+	mlxfw_status_notify(mlxfw_dev, "Downloading component",
+			    comp_name, 0, comp->data_size);
 	for (offset = 0;
 	     offset < MLXFW_ALIGN_UP(comp->data_size, comp_align_bits);
 	     offset += comp_max_write_size) {
@@ -131,9 +147,13 @@ static int mlxfw_flash_component(struct mlxfw_dev *mlxfw_dev,
 							 offset);
 		if (err)
 			goto err_out;
+		mlxfw_status_notify(mlxfw_dev, "Downloading component",
+				    comp_name, offset + block_size,
+				    comp->data_size);
 	}
 
 	pr_debug("Component verify\n");
+	mlxfw_status_notify(mlxfw_dev, "Verifying component", comp_name, 0, 0);
 	err = mlxfw_dev->ops->fsm_component_verify(mlxfw_dev, fwhandle,
 						   comp->index);
 	if (err)
@@ -203,6 +223,8 @@ int mlxfw_firmware_flash(struct mlxfw_dev *mlxfw_dev,
 		return PTR_ERR(mfa2_file);
 
 	pr_info("Initialize firmware flash process\n");
+	mlxfw_status_notify(mlxfw_dev, "Initializing firmware flash process",
+			    NULL, 0, 0);
 	err = mlxfw_dev->ops->fsm_lock(mlxfw_dev, &fwhandle);
 	if (err) {
 		pr_err("Could not lock the firmware FSM\n");
@@ -220,6 +242,7 @@ int mlxfw_firmware_flash(struct mlxfw_dev *mlxfw_dev,
 		goto err_flash_components;
 
 	pr_debug("Activate image\n");
+	mlxfw_status_notify(mlxfw_dev, "Activating image", NULL, 0, 0);
 	err = mlxfw_dev->ops->fsm_activate(mlxfw_dev, fwhandle);
 	if (err) {
 		pr_err("Could not activate the downloaded image\n");
@@ -236,6 +259,7 @@ int mlxfw_firmware_flash(struct mlxfw_dev *mlxfw_dev,
 	mlxfw_dev->ops->fsm_release(mlxfw_dev, fwhandle);
 
 	pr_info("Firmware flash done.\n");
+	mlxfw_status_notify(mlxfw_dev, "Firmware flash done", NULL, 0, 0);
 	mlxfw_mfa2_file_fini(mfa2_file);
 	return 0;
 
-- 
2.17.2


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

* [patch net-next v3 6/8] mlxsw: Implement flash update status notifications
  2019-06-04 13:40 [patch net-next v3 0/8] expose flash update status to user Jiri Pirko
                   ` (4 preceding siblings ...)
  2019-06-04 13:40 ` [patch net-next v3 5/8] mlxfw: Introduce status_notify op and call it to notify about the status Jiri Pirko
@ 2019-06-04 13:40 ` Jiri Pirko
  2019-06-04 13:40 ` [patch net-next v3 7/8] netdevsim: implement fake flash updating with notifications Jiri Pirko
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2019-06-04 13:40 UTC (permalink / raw)
  To: netdev
  Cc: davem, mlxsw, jakub.kicinski, sthemmin, dsahern, saeedm, leon,
	f.fainelli

From: Jiri Pirko <jiri@mellanox.com>

Implement mlxfw status_notify op by passing notification down to
devlink. Also notify about flash update begin and end.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 2cba678863bd..417e7c9273ef 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -294,6 +294,19 @@ static void mlxsw_sp_fsm_release(struct mlxfw_dev *mlxfw_dev, u32 fwhandle)
 	mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mcc), mcc_pl);
 }
 
+static void mlxsw_sp_status_notify(struct mlxfw_dev *mlxfw_dev,
+				   const char *msg, const char *comp_name,
+				   u32 done_bytes, u32 total_bytes)
+{
+	struct mlxsw_sp_mlxfw_dev *mlxsw_sp_mlxfw_dev =
+		container_of(mlxfw_dev, struct mlxsw_sp_mlxfw_dev, mlxfw_dev);
+	struct mlxsw_sp *mlxsw_sp = mlxsw_sp_mlxfw_dev->mlxsw_sp;
+
+	devlink_flash_update_status_notify(priv_to_devlink(mlxsw_sp->core),
+					   msg, comp_name,
+					   done_bytes, total_bytes);
+}
+
 static const struct mlxfw_dev_ops mlxsw_sp_mlxfw_dev_ops = {
 	.component_query	= mlxsw_sp_component_query,
 	.fsm_lock		= mlxsw_sp_fsm_lock,
@@ -303,7 +316,8 @@ static const struct mlxfw_dev_ops mlxsw_sp_mlxfw_dev_ops = {
 	.fsm_activate		= mlxsw_sp_fsm_activate,
 	.fsm_query_state	= mlxsw_sp_fsm_query_state,
 	.fsm_cancel		= mlxsw_sp_fsm_cancel,
-	.fsm_release		= mlxsw_sp_fsm_release
+	.fsm_release		= mlxsw_sp_fsm_release,
+	.status_notify		= mlxsw_sp_status_notify,
 };
 
 static int mlxsw_sp_firmware_flash(struct mlxsw_sp *mlxsw_sp,
@@ -321,8 +335,10 @@ static int mlxsw_sp_firmware_flash(struct mlxsw_sp *mlxsw_sp,
 	int err;
 
 	mlxsw_core_fw_flash_start(mlxsw_sp->core);
+	devlink_flash_update_begin_notify(priv_to_devlink(mlxsw_sp->core));
 	err = mlxfw_firmware_flash(&mlxsw_sp_mlxfw_dev.mlxfw_dev,
 				   firmware, extack);
+	devlink_flash_update_end_notify(priv_to_devlink(mlxsw_sp->core));
 	mlxsw_core_fw_flash_end(mlxsw_sp->core);
 
 	return err;
-- 
2.17.2


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

* [patch net-next v3 7/8] netdevsim: implement fake flash updating with notifications
  2019-06-04 13:40 [patch net-next v3 0/8] expose flash update status to user Jiri Pirko
                   ` (5 preceding siblings ...)
  2019-06-04 13:40 ` [patch net-next v3 6/8] mlxsw: Implement flash update status notifications Jiri Pirko
@ 2019-06-04 13:40 ` Jiri Pirko
  2019-06-04 17:54   ` Jakub Kicinski
  2019-06-04 13:40 ` [patch net-next v3 8/8] selftests: add basic netdevsim devlink flash testing Jiri Pirko
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 24+ messages in thread
From: Jiri Pirko @ 2019-06-04 13:40 UTC (permalink / raw)
  To: netdev
  Cc: davem, mlxsw, jakub.kicinski, sthemmin, dsahern, saeedm, leon,
	f.fainelli

From: Jiri Pirko <jiri@mellanox.com>

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
v1->v2:
- added debugfs toggle to enable/disable flash status notifications
---
 drivers/net/netdevsim/dev.c       | 44 +++++++++++++++++++++++++++++++
 drivers/net/netdevsim/netdevsim.h |  1 +
 2 files changed, 45 insertions(+)

diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
index b509b941d5ca..c5c417a3c0ce 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -38,6 +38,8 @@ static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev)
 	nsim_dev->ports_ddir = debugfs_create_dir("ports", nsim_dev->ddir);
 	if (IS_ERR_OR_NULL(nsim_dev->ports_ddir))
 		return PTR_ERR_OR_ZERO(nsim_dev->ports_ddir) ?: -EINVAL;
+	debugfs_create_bool("fw_update_status", 0600, nsim_dev->ddir,
+			    &nsim_dev->fw_update_status);
 	return 0;
 }
 
@@ -220,8 +222,49 @@ static int nsim_dev_reload(struct devlink *devlink,
 	return 0;
 }
 
+#define NSIM_DEV_FLASH_SIZE 500000
+#define NSIM_DEV_FLASH_CHUNK_SIZE 1000
+#define NSIM_DEV_FLASH_CHUNK_TIME_MS 10
+
+static int nsim_dev_flash_update(struct devlink *devlink, const char *file_name,
+				 const char *component,
+				 struct netlink_ext_ack *extack)
+{
+	struct nsim_dev *nsim_dev = devlink_priv(devlink);
+	int i;
+
+	if (nsim_dev->fw_update_status) {
+		devlink_flash_update_begin_notify(devlink);
+		devlink_flash_update_status_notify(devlink,
+						   "Preparing to flash",
+						   component, 0, 0);
+	}
+
+	for (i = 0; i < NSIM_DEV_FLASH_SIZE / NSIM_DEV_FLASH_CHUNK_SIZE; i++) {
+		if (nsim_dev->fw_update_status)
+			devlink_flash_update_status_notify(devlink, "Flashing",
+							   component,
+							   i * NSIM_DEV_FLASH_CHUNK_SIZE,
+							   NSIM_DEV_FLASH_SIZE);
+		msleep(NSIM_DEV_FLASH_CHUNK_TIME_MS);
+	}
+
+	if (nsim_dev->fw_update_status) {
+		devlink_flash_update_status_notify(devlink, "Flashing",
+						   component,
+						   NSIM_DEV_FLASH_SIZE,
+						   NSIM_DEV_FLASH_SIZE);
+		devlink_flash_update_status_notify(devlink, "Flashing done",
+						   component, 0, 0);
+		devlink_flash_update_end_notify(devlink);
+	}
+
+	return 0;
+}
+
 static const struct devlink_ops nsim_dev_devlink_ops = {
 	.reload = nsim_dev_reload,
+	.flash_update = nsim_dev_flash_update,
 };
 
 static struct nsim_dev *
@@ -240,6 +283,7 @@ nsim_dev_create(struct nsim_bus_dev *nsim_bus_dev, unsigned int port_count)
 	get_random_bytes(nsim_dev->switch_id.id, nsim_dev->switch_id.id_len);
 	INIT_LIST_HEAD(&nsim_dev->port_list);
 	mutex_init(&nsim_dev->port_list_lock);
+	nsim_dev->fw_update_status = true;
 
 	nsim_dev->fib_data = nsim_fib_create();
 	if (IS_ERR(nsim_dev->fib_data)) {
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index 3f398797c2bc..79c05af2a7c0 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -157,6 +157,7 @@ struct nsim_dev {
 	struct netdev_phys_item_id switch_id;
 	struct list_head port_list;
 	struct mutex port_list_lock; /* protects port list */
+	bool fw_update_status;
 };
 
 int nsim_dev_init(void);
-- 
2.17.2


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

* [patch net-next v3 8/8] selftests: add basic netdevsim devlink flash testing
  2019-06-04 13:40 [patch net-next v3 0/8] expose flash update status to user Jiri Pirko
                   ` (6 preceding siblings ...)
  2019-06-04 13:40 ` [patch net-next v3 7/8] netdevsim: implement fake flash updating with notifications Jiri Pirko
@ 2019-06-04 13:40 ` Jiri Pirko
  2019-06-04 17:55   ` Jakub Kicinski
  2019-06-04 13:44 ` [patch net-next v3 1/3] header update Jiri Pirko
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 24+ messages in thread
From: Jiri Pirko @ 2019-06-04 13:40 UTC (permalink / raw)
  To: netdev
  Cc: davem, mlxsw, jakub.kicinski, sthemmin, dsahern, saeedm, leon,
	f.fainelli

From: Jiri Pirko <jiri@mellanox.com>

Utilizes the devlink flash code.

Suggested-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
v2->v3:
- new patch
---
 .../drivers/net/netdevsim/devlink.sh          | 53 +++++++++++++++++++
 1 file changed, 53 insertions(+)
 create mode 100755 tools/testing/selftests/drivers/net/netdevsim/devlink.sh

diff --git a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
new file mode 100755
index 000000000000..9d8baf5d14b3
--- /dev/null
+++ b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+lib_dir=$(dirname $0)/../../../net/forwarding
+
+ALL_TESTS="fw_flash_test"
+NUM_NETIFS=0
+source $lib_dir/lib.sh
+
+BUS_ADDR=10
+PORT_COUNT=4
+DEV_NAME=netdevsim$BUS_ADDR
+SYSFS_NET_DIR=/sys/bus/netdevsim/devices/$DEV_NAME/net/
+DEBUGFS_DIR=/sys/kernel/debug/netdevsim/$DEV_NAME/
+DL_HANDLE=netdevsim/$DEV_NAME
+
+fw_flash_test()
+{
+	RET=0
+
+	devlink dev flash $DL_HANDLE file dummy
+	check_err $? "Failed to flash with status updates on"
+
+	echo "n"> $DEBUGFS_DIR/fw_update_status
+	check_err $? "Failed to disable status updates"
+
+	devlink dev flash $DL_HANDLE file dummy
+	check_err $? "Failed to flash with status updates off"
+
+	log_test "fw flash test"
+}
+
+setup_prepare()
+{
+	modprobe netdevsim
+	echo "$BUS_ADDR $PORT_COUNT" > /sys/bus/netdevsim/new_device
+	while [ ! -d $SYSFS_NET_DIR ] ; do :; done
+}
+
+cleanup()
+{
+	pre_cleanup
+	echo "$BUS_ADDR" > /sys/bus/netdevsim/del_device
+	modprobe -r netdevsim
+}
+
+trap cleanup EXIT
+
+setup_prepare
+
+tests_run
+
+exit $EXIT_STATUS
-- 
2.17.2


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

* [patch net-next v3 1/3] header update
  2019-06-04 13:40 [patch net-next v3 0/8] expose flash update status to user Jiri Pirko
                   ` (7 preceding siblings ...)
  2019-06-04 13:40 ` [patch net-next v3 8/8] selftests: add basic netdevsim devlink flash testing Jiri Pirko
@ 2019-06-04 13:44 ` Jiri Pirko
  2019-06-04 13:54   ` Jiri Pirko
  2019-06-04 13:44 ` [patch net-next v3 2/3] devlink: implement flash update status monitoring Jiri Pirko
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 24+ messages in thread
From: Jiri Pirko @ 2019-06-04 13:44 UTC (permalink / raw)
  To: netdev
  Cc: davem, mlxsw, jakub.kicinski, sthemmin, dsahern, saeedm, leon,
	f.fainelli

From: Jiri Pirko <jiri@mellanox.com>

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 include/uapi/linux/devlink.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index 3b6a9e6be3ac..6544824a0b97 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -104,6 +104,8 @@ enum devlink_command {
 	DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR,
 
 	DEVLINK_CMD_FLASH_UPDATE,
+	DEVLINK_CMD_FLASH_UPDATE_END,		/* notification only */
+	DEVLINK_CMD_FLASH_UPDATE_STATUS,	/* notification only */
 
 	/* add new commands above here */
 	__DEVLINK_CMD_MAX,
@@ -331,6 +333,9 @@ enum devlink_attr {
 
 	DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME,	/* string */
 	DEVLINK_ATTR_FLASH_UPDATE_COMPONENT,	/* string */
+	DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG,	/* string */
+	DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE,	/* u64 */
+	DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL,	/* u64 */
 
 	/* add new attributes above here, update the policy in devlink.c */
 
-- 
2.17.2


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

* [patch net-next v3 2/3] devlink: implement flash update status monitoring
  2019-06-04 13:40 [patch net-next v3 0/8] expose flash update status to user Jiri Pirko
                   ` (8 preceding siblings ...)
  2019-06-04 13:44 ` [patch net-next v3 1/3] header update Jiri Pirko
@ 2019-06-04 13:44 ` Jiri Pirko
  2019-06-04 13:44 ` [patch net-next v3 3/3] devlink: implement flash " Jiri Pirko
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2019-06-04 13:44 UTC (permalink / raw)
  To: netdev
  Cc: davem, mlxsw, jakub.kicinski, sthemmin, dsahern, saeedm, leon,
	f.fainelli

From: Jiri Pirko <jiri@mellanox.com>

Kernel sends notifications about flash update status, so implement these
messages for monitoring.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 devlink/devlink.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index 436935f88bda..55cbc01189db 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -414,6 +414,10 @@ static const enum mnl_attr_data_type devlink_policy[DEVLINK_ATTR_MAX + 1] = {
 	[DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT] = MNL_TYPE_U64,
 	[DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS] = MNL_TYPE_U64,
 	[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] = MNL_TYPE_U64,
+	[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT] = MNL_TYPE_STRING,
+	[DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG] = MNL_TYPE_STRING,
+	[DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE] = MNL_TYPE_U64,
+	[DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL] = MNL_TYPE_U64,
 };
 
 static int attr_cb(const struct nlattr *attr, void *data)
@@ -3712,6 +3716,9 @@ static const char *cmd_name(uint8_t cmd)
 	case DEVLINK_CMD_REGION_SET: return "set";
 	case DEVLINK_CMD_REGION_NEW: return "new";
 	case DEVLINK_CMD_REGION_DEL: return "del";
+	case DEVLINK_CMD_FLASH_UPDATE: return "begin";
+	case DEVLINK_CMD_FLASH_UPDATE_END: return "end";
+	case DEVLINK_CMD_FLASH_UPDATE_STATUS: return "status";
 	default: return "<unknown cmd>";
 	}
 }
@@ -3740,6 +3747,10 @@ static const char *cmd_obj(uint8_t cmd)
 	case DEVLINK_CMD_REGION_NEW:
 	case DEVLINK_CMD_REGION_DEL:
 		return "region";
+	case DEVLINK_CMD_FLASH_UPDATE:
+	case DEVLINK_CMD_FLASH_UPDATE_END:
+	case DEVLINK_CMD_FLASH_UPDATE_STATUS:
+		return "flash";
 	default: return "<unknown obj>";
 	}
 }
@@ -3764,6 +3775,29 @@ static bool cmd_filter_check(struct dl *dl, uint8_t cmd)
 	return false;
 }
 
+static void pr_out_flash_update(struct dl *dl, struct nlattr **tb)
+{
+	__pr_out_handle_start(dl, tb, true, false);
+
+	if (tb[DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG])
+		pr_out_str(dl, "msg",
+			   mnl_attr_get_str(tb[DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG]));
+
+	if (tb[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT])
+		pr_out_str(dl, "component",
+			   mnl_attr_get_str(tb[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT]));
+
+	if (tb[DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE])
+		pr_out_u64(dl, "done",
+			   mnl_attr_get_u64(tb[DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE]));
+
+	if (tb[DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL])
+		pr_out_u64(dl, "total",
+			   mnl_attr_get_u64(tb[DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL]));
+
+	pr_out_handle_end(dl);
+}
+
 static void pr_out_region(struct dl *dl, struct nlattr **tb);
 
 static int cmd_mon_show_cb(const struct nlmsghdr *nlh, void *data)
@@ -3820,6 +3854,15 @@ static int cmd_mon_show_cb(const struct nlmsghdr *nlh, void *data)
 		pr_out_mon_header(genl->cmd);
 		pr_out_region(dl, tb);
 		break;
+	case DEVLINK_CMD_FLASH_UPDATE: /* fall through */
+	case DEVLINK_CMD_FLASH_UPDATE_END: /* fall through */
+	case DEVLINK_CMD_FLASH_UPDATE_STATUS:
+		mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
+		if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME])
+			return MNL_CB_ERROR;
+		pr_out_mon_header(genl->cmd);
+		pr_out_flash_update(dl, tb);
+		break;
 	}
 	return MNL_CB_OK;
 }
-- 
2.17.2


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

* [patch net-next v3 3/3] devlink: implement flash status monitoring
  2019-06-04 13:40 [patch net-next v3 0/8] expose flash update status to user Jiri Pirko
                   ` (9 preceding siblings ...)
  2019-06-04 13:44 ` [patch net-next v3 2/3] devlink: implement flash update status monitoring Jiri Pirko
@ 2019-06-04 13:44 ` Jiri Pirko
  2019-06-10 17:09   ` David Ahern
  2019-06-04 15:09 ` [patch net-next v3 0/8] expose flash update status to user Alexei Starovoitov
  2019-06-04 21:21 ` David Miller
  12 siblings, 1 reply; 24+ messages in thread
From: Jiri Pirko @ 2019-06-04 13:44 UTC (permalink / raw)
  To: netdev
  Cc: davem, mlxsw, jakub.kicinski, sthemmin, dsahern, saeedm, leon,
	f.fainelli

From: Jiri Pirko <jiri@mellanox.com>

Listen to status notifications coming from kernel during flashing and
put them on stdout to inform user about the status.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
v2->v3:
- added example in man
v1->v2:
- fixed endless loop bug in case of no notifications
---
 devlink/devlink.c      | 209 ++++++++++++++++++++++++++++++++++++++++-
 devlink/mnlg.c         |   5 +
 devlink/mnlg.h         |   1 +
 man/man8/devlink-dev.8 |  11 +++
 4 files changed, 222 insertions(+), 4 deletions(-)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index 55cbc01189db..05514312782a 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -24,6 +24,7 @@
 #include <netinet/ether.h>
 #include <sys/sysinfo.h>
 #include <sys/queue.h>
+#include <sys/types.h>
 
 #include "SNAPSHOT.h"
 #include "list.h"
@@ -68,6 +69,12 @@ static int g_new_line_count;
 		g_new_line_count = 0;				\
 	} while (0)
 
+#define pr_out_tty(args...)					\
+	do {							\
+		if (isatty(STDOUT_FILENO))			\
+			fprintf(stdout, ##args);		\
+	} while (0)
+
 static int g_indent_level;
 static bool g_indent_newline;
 #define INDENT_STR_STEP 2
@@ -113,9 +120,8 @@ static int _mnlg_socket_recv_run(struct mnlg_socket *nlg,
 	return 0;
 }
 
-static int _mnlg_socket_sndrcv(struct mnlg_socket *nlg,
-			       const struct nlmsghdr *nlh,
-			       mnl_cb_t data_cb, void *data)
+static int _mnlg_socket_send(struct mnlg_socket *nlg,
+			     const struct nlmsghdr *nlh)
 {
 	int err;
 
@@ -124,6 +130,18 @@ static int _mnlg_socket_sndrcv(struct mnlg_socket *nlg,
 		pr_err("Failed to call mnlg_socket_send\n");
 		return -errno;
 	}
+	return 0;
+}
+
+static int _mnlg_socket_sndrcv(struct mnlg_socket *nlg,
+			       const struct nlmsghdr *nlh,
+			       mnl_cb_t data_cb, void *data)
+{
+	int err;
+
+	err = _mnlg_socket_send(nlg, nlh);
+	if (err)
+		return err;
 	return _mnlg_socket_recv_run(nlg, data_cb, data);
 }
 
@@ -2697,9 +2715,151 @@ static void cmd_dev_flash_help(void)
 	pr_err("Usage: devlink dev flash DEV file PATH [ component NAME ]\n");
 }
 
+
+struct cmd_dev_flash_status_ctx {
+	struct dl *dl;
+	char *last_msg;
+	char *last_component;
+	uint8_t not_first:1,
+		last_pc:1,
+		received_end:1,
+		flash_done:1;
+};
+
+static int nullstrcmp(const char *str1, const char *str2)
+{
+	if (str1 && str2)
+		return strcmp(str1, str2);
+	if (!str1 && !str2)
+		return 0;
+	return str1 ? 1 : -1;
+}
+
+static int cmd_dev_flash_status_cb(const struct nlmsghdr *nlh, void *data)
+{
+	struct cmd_dev_flash_status_ctx *ctx = data;
+	struct dl_opts *opts = &ctx->dl->opts;
+	struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
+	struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
+	const char *component = NULL;
+	uint64_t done = 0, total = 0;
+	const char *msg = NULL;
+	const char *bus_name;
+	const char *dev_name;
+
+	if (genl->cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS &&
+	    genl->cmd != DEVLINK_CMD_FLASH_UPDATE_END)
+		return MNL_CB_STOP;
+
+	mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
+	if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME])
+		return MNL_CB_ERROR;
+	bus_name = mnl_attr_get_str(tb[DEVLINK_ATTR_BUS_NAME]);
+	dev_name = mnl_attr_get_str(tb[DEVLINK_ATTR_DEV_NAME]);
+	if (strcmp(bus_name, opts->bus_name) ||
+	    strcmp(dev_name, opts->dev_name))
+		return MNL_CB_ERROR;
+
+	if (genl->cmd == DEVLINK_CMD_FLASH_UPDATE_END && ctx->not_first) {
+		pr_out("\n");
+		free(ctx->last_msg);
+		free(ctx->last_component);
+		ctx->received_end = 1;
+		return MNL_CB_STOP;
+	}
+
+	if (tb[DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG])
+		msg = mnl_attr_get_str(tb[DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG]);
+	if (tb[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT])
+		component = mnl_attr_get_str(tb[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT]);
+	if (tb[DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE])
+		done = mnl_attr_get_u64(tb[DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE]);
+	if (tb[DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL])
+		total = mnl_attr_get_u64(tb[DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL]);
+
+	if (!nullstrcmp(msg, ctx->last_msg) &&
+	    !nullstrcmp(component, ctx->last_component) &&
+	    ctx->last_pc && ctx->not_first) {
+		pr_out_tty("\b\b\b\b\b"); /* clean percentage */
+	} else {
+		if (ctx->not_first)
+			pr_out("\n");
+		if (component) {
+			pr_out("[%s] ", component);
+			free(ctx->last_component);
+			ctx->last_component = strdup(component);
+		}
+		if (msg) {
+			pr_out("%s", msg);
+			free(ctx->last_msg);
+			ctx->last_msg = strdup(msg);
+		}
+	}
+	if (total) {
+		pr_out_tty(" %3lu%%", (done * 100) / total);
+		ctx->last_pc = 1;
+	} else {
+		ctx->last_pc = 0;
+	}
+	fflush(stdout);
+	ctx->not_first = 1;
+
+	return MNL_CB_STOP;
+}
+
+static int cmd_dev_flash_fds_process(struct cmd_dev_flash_status_ctx *ctx,
+				     struct mnlg_socket *nlg_ntf,
+				     int pipe_r)
+{
+	int nlfd = mnlg_socket_get_fd(nlg_ntf);
+	fd_set fds[3];
+	int fdmax;
+	int i;
+	int err;
+	int err2;
+
+	for (i = 0; i < 3; i++)
+		FD_ZERO(&fds[i]);
+	FD_SET(pipe_r, &fds[0]);
+	fdmax = pipe_r + 1;
+	FD_SET(nlfd, &fds[0]);
+	if (nlfd >= fdmax)
+		fdmax = nlfd + 1;
+
+	while (select(fdmax, &fds[0], &fds[1], &fds[2], NULL) < 0) {
+		if (errno == EINTR)
+			continue;
+		pr_err("select() failed\n");
+		return -errno;
+	}
+	if (FD_ISSET(nlfd, &fds[0])) {
+		err = _mnlg_socket_recv_run(nlg_ntf,
+					    cmd_dev_flash_status_cb, ctx);
+		if (err)
+			return err;
+	}
+	if (FD_ISSET(pipe_r, &fds[0])) {
+		err = read(pipe_r, &err2, sizeof(err2));
+		if (err == -1) {
+			pr_err("Failed to read pipe\n");
+			return -errno;
+		}
+		if (err2)
+			return err2;
+		ctx->flash_done = 1;
+	}
+	return 0;
+}
+
+
 static int cmd_dev_flash(struct dl *dl)
 {
+	struct cmd_dev_flash_status_ctx ctx = {.dl = dl,};
+	struct mnlg_socket *nlg_ntf;
 	struct nlmsghdr *nlh;
+	int pipe_r, pipe_w;
+	int pipe_fds[2];
+	pid_t pid;
 	int err;
 
 	if (dl_argv_match(dl, "help") || dl_no_arg(dl)) {
@@ -2715,7 +2875,48 @@ static int cmd_dev_flash(struct dl *dl)
 	if (err)
 		return err;
 
-	return _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL);
+	nlg_ntf = mnlg_socket_open(DEVLINK_GENL_NAME, DEVLINK_GENL_VERSION);
+	if (!nlg_ntf)
+		return err;
+
+	err = _mnlg_socket_group_add(nlg_ntf, DEVLINK_GENL_MCGRP_CONFIG_NAME);
+	if (err)
+		return err;
+
+	err = pipe(pipe_fds);
+	if (err == -1)
+		return -errno;
+	pipe_r = pipe_fds[0];
+	pipe_w = pipe_fds[1];
+
+	pid = fork();
+	if (pid == -1) {
+		close(pipe_r);
+		close(pipe_w);
+		return -errno;
+	} else if (!pid) {
+		/* In child, just execute the flash and pass returned
+		 * value through pipe once it is done.
+		 */
+		close(pipe_r);
+		err = _mnlg_socket_send(dl->nlg, nlh);
+		write(pipe_w, &err, sizeof(err));
+		close(pipe_w);
+		exit(0);
+	}
+	close(pipe_w);
+
+	do {
+		err = cmd_dev_flash_fds_process(&ctx, nlg_ntf, pipe_r);
+		if (err)
+			goto out;
+	} while (!ctx.flash_done || (ctx.not_first && !ctx.received_end));
+
+	err = _mnlg_socket_recv_run(dl->nlg, NULL, NULL);
+out:
+	close(pipe_r);
+	mnlg_socket_close(nlg_ntf);
+	return err;
 }
 
 static int cmd_dev(struct dl *dl)
diff --git a/devlink/mnlg.c b/devlink/mnlg.c
index 37cc25ddf490..f5a5dbe7f64f 100644
--- a/devlink/mnlg.c
+++ b/devlink/mnlg.c
@@ -313,3 +313,8 @@ void mnlg_socket_close(struct mnlg_socket *nlg)
 	free(nlg->buf);
 	free(nlg);
 }
+
+int mnlg_socket_get_fd(struct mnlg_socket *nlg)
+{
+	return mnl_socket_get_fd(nlg->nl);
+}
diff --git a/devlink/mnlg.h b/devlink/mnlg.h
index 4d1babf3b4c2..61bc5a3f31aa 100644
--- a/devlink/mnlg.h
+++ b/devlink/mnlg.h
@@ -23,5 +23,6 @@ int mnlg_socket_recv_run(struct mnlg_socket *nlg, mnl_cb_t data_cb, void *data);
 int mnlg_socket_group_add(struct mnlg_socket *nlg, const char *group_name);
 struct mnlg_socket *mnlg_socket_open(const char *family_name, uint8_t version);
 void mnlg_socket_close(struct mnlg_socket *nlg);
+int mnlg_socket_get_fd(struct mnlg_socket *nlg);
 
 #endif /* _MNLG_H_ */
diff --git a/man/man8/devlink-dev.8 b/man/man8/devlink-dev.8
index 1804463b2321..1021ee8d064c 100644
--- a/man/man8/devlink-dev.8
+++ b/man/man8/devlink-dev.8
@@ -244,6 +244,17 @@ Sets the parameter internal_error_reset of specified devlink device to true.
 devlink dev reload pci/0000:01:00.0
 .RS 4
 Performs hot reload of specified devlink device.
+.RE
+.PP
+devlink dev flash pci/0000:01:00.0 file firmware.bin
+.RS 4
+Flashes the specified devlink device with provided firmware file name. If the driver supports it, user gets updates about the flash status. For example:
+.br
+Preparing to flash
+.br
+Flashing 100%
+.br
+Flashing done
 
 .SH SEE ALSO
 .BR devlink (8),
-- 
2.17.2


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

* Re: [patch net-next v3 1/3] header update
  2019-06-04 13:44 ` [patch net-next v3 1/3] header update Jiri Pirko
@ 2019-06-04 13:54   ` Jiri Pirko
  0 siblings, 0 replies; 24+ messages in thread
From: Jiri Pirko @ 2019-06-04 13:54 UTC (permalink / raw)
  To: netdev
  Cc: davem, mlxsw, jakub.kicinski, sthemmin, dsahern, saeedm, leon,
	f.fainelli

This and next 2 patches are aimed at iproute2/net-next. Sorry for
messing up the subject prefix.

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

* Re: [patch net-next v3 0/8] expose flash update status to user
  2019-06-04 13:40 [patch net-next v3 0/8] expose flash update status to user Jiri Pirko
                   ` (10 preceding siblings ...)
  2019-06-04 13:44 ` [patch net-next v3 3/3] devlink: implement flash " Jiri Pirko
@ 2019-06-04 15:09 ` Alexei Starovoitov
  2019-06-04 21:21 ` David Miller
  12 siblings, 0 replies; 24+ messages in thread
From: Alexei Starovoitov @ 2019-06-04 15:09 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: Network Development, David S. Miller, mlxsw, Jakub Kicinski,
	Stephen Hemminger, David Ahern, Saeed Mahameed, Leon Romanovsky,
	Florian Fainelli

On Tue, Jun 4, 2019 at 6:41 AM Jiri Pirko <jiri@resnulli.us> wrote:
>
> From: Jiri Pirko <jiri@mellanox.com>
>
> When user is flashing device using devlink, he currenly does not see any
> information about what is going on, percentages, etc.
> Drivers, for example mlxsw and mlx5, have notion about the progress
> and what is happening. This patchset exposes this progress
> information to userspace.
>
> Example output for existing flash command:
> $ devlink dev flash pci/0000:01:00.0 file firmware.bin
> Preparing to flash
> Flashing 100%
> Flashing done
>
> See this console recording which shows flashing FW on a Mellanox
> Spectrum device:
> https://asciinema.org/a/247926

from api perspective it looks good to me.
Thanks!
Acked-by: Alexei Starovoitov <ast@kernel.org>

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

* Re: [patch net-next v3 7/8] netdevsim: implement fake flash updating with notifications
  2019-06-04 13:40 ` [patch net-next v3 7/8] netdevsim: implement fake flash updating with notifications Jiri Pirko
@ 2019-06-04 17:54   ` Jakub Kicinski
  0 siblings, 0 replies; 24+ messages in thread
From: Jakub Kicinski @ 2019-06-04 17:54 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: netdev, davem, mlxsw, sthemmin, dsahern, saeedm, leon, f.fainelli

On Tue,  4 Jun 2019 15:40:43 +0200, Jiri Pirko wrote:
> From: Jiri Pirko <jiri@mellanox.com>
> 
> Signed-off-by: Jiri Pirko <jiri@mellanox.com>

Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>

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

* Re: [patch net-next v3 8/8] selftests: add basic netdevsim devlink flash testing
  2019-06-04 13:40 ` [patch net-next v3 8/8] selftests: add basic netdevsim devlink flash testing Jiri Pirko
@ 2019-06-04 17:55   ` Jakub Kicinski
  0 siblings, 0 replies; 24+ messages in thread
From: Jakub Kicinski @ 2019-06-04 17:55 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: netdev, davem, mlxsw, sthemmin, dsahern, saeedm, leon, f.fainelli

On Tue,  4 Jun 2019 15:40:44 +0200, Jiri Pirko wrote:
> From: Jiri Pirko <jiri@mellanox.com>
> 
> Utilizes the devlink flash code.
> 
> Suggested-by: Jakub Kicinski <jakub.kicinski@netronome.com>
> Signed-off-by: Jiri Pirko <jiri@mellanox.com>

Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com>

All looks good too me now, thanks Jiri!

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

* Re: [patch net-next v3 2/8] mlx5: Move firmware flash implementation to devlink
  2019-06-04 13:40 ` [patch net-next v3 2/8] mlx5: " Jiri Pirko
@ 2019-06-04 18:40   ` Saeed Mahameed
  0 siblings, 0 replies; 24+ messages in thread
From: Saeed Mahameed @ 2019-06-04 18:40 UTC (permalink / raw)
  To: jiri, netdev
  Cc: sthemmin, dsahern, f.fainelli, davem, mlxsw, jakub.kicinski, leon

On Tue, 2019-06-04 at 15:40 +0200, Jiri Pirko wrote:
> From: Jiri Pirko <jiri@mellanox.com>
> 
> Benefit from the devlink flash update implementation and ethtool
> fallback to it and move firmware flash implementation there.
> 
> Signed-off-by: Jiri Pirko <jiri@mellanox.com>

Acked-by: Saeed Mahameed <saeedm@mellanox.com>

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

* Re: [patch net-next v3 0/8] expose flash update status to user
  2019-06-04 13:40 [patch net-next v3 0/8] expose flash update status to user Jiri Pirko
                   ` (11 preceding siblings ...)
  2019-06-04 15:09 ` [patch net-next v3 0/8] expose flash update status to user Alexei Starovoitov
@ 2019-06-04 21:21 ` David Miller
  12 siblings, 0 replies; 24+ messages in thread
From: David Miller @ 2019-06-04 21:21 UTC (permalink / raw)
  To: jiri
  Cc: netdev, mlxsw, jakub.kicinski, sthemmin, dsahern, saeedm, leon,
	f.fainelli

From: Jiri Pirko <jiri@resnulli.us>
Date: Tue,  4 Jun 2019 15:40:36 +0200

> From: Jiri Pirko <jiri@mellanox.com>
> 
> When user is flashing device using devlink, he currenly does not see any
> information about what is going on, percentages, etc.
> Drivers, for example mlxsw and mlx5, have notion about the progress
> and what is happening. This patchset exposes this progress
> information to userspace.
> 
> Example output for existing flash command:
> $ devlink dev flash pci/0000:01:00.0 file firmware.bin
> Preparing to flash
> Flashing 100%
> Flashing done
> 
> See this console recording which shows flashing FW on a Mellanox
> Spectrum device:
> https://asciinema.org/a/247926

Series applied, thanks.

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

* Re: [patch net-next v3 3/3] devlink: implement flash status monitoring
  2019-06-04 13:44 ` [patch net-next v3 3/3] devlink: implement flash " Jiri Pirko
@ 2019-06-10 17:09   ` David Ahern
  2019-06-10 17:24     ` Jakub Kicinski
  0 siblings, 1 reply; 24+ messages in thread
From: David Ahern @ 2019-06-10 17:09 UTC (permalink / raw)
  To: Jiri Pirko, netdev
  Cc: davem, mlxsw, jakub.kicinski, sthemmin, saeedm, leon, f.fainelli

On 6/4/19 7:44 AM, Jiri Pirko wrote:
> diff --git a/man/man8/devlink-dev.8 b/man/man8/devlink-dev.8
> index 1804463b2321..1021ee8d064c 100644
> --- a/man/man8/devlink-dev.8
> +++ b/man/man8/devlink-dev.8
> @@ -244,6 +244,17 @@ Sets the parameter internal_error_reset of specified devlink device to true.
>  devlink dev reload pci/0000:01:00.0
>  .RS 4
>  Performs hot reload of specified devlink device.
> +.RE
> +.PP
> +devlink dev flash pci/0000:01:00.0 file firmware.bin
> +.RS 4
> +Flashes the specified devlink device with provided firmware file name. If the driver supports it, user gets updates about the flash status. For example:
> +.br
> +Preparing to flash
> +.br
> +Flashing 100%
> +.br
> +Flashing done
>  
>  .SH SEE ALSO
>  .BR devlink (8),

something is missing here from a user perspective at least:

root@mlx-2700-05:~# ./devlink dev
pci/0000:03:00.0

root@mlx-2700-05:~# ./devlink dev flash pci/0000:03:00.0 file
/lib/firmware/mellanox/mlxsw_spectrum-13.2000.1122.mfa2
devlink answers: No such file or directory

root@mlx-2700-05:~# ls -l
/lib/firmware/mellanox/mlxsw_spectrum-13.2000.1122.mfa2
-rw-r--r-- 1 cumulus 1001 994184 May 14 22:44
/lib/firmware/mellanox/mlxsw_spectrum-13.2000.1122.mfa2


Why the 'no such file' response when the file exists?

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

* Re: [patch net-next v3 3/3] devlink: implement flash status monitoring
  2019-06-10 17:09   ` David Ahern
@ 2019-06-10 17:24     ` Jakub Kicinski
  2019-06-10 17:30       ` David Ahern
  0 siblings, 1 reply; 24+ messages in thread
From: Jakub Kicinski @ 2019-06-10 17:24 UTC (permalink / raw)
  To: David Ahern
  Cc: Jiri Pirko, netdev, davem, mlxsw, sthemmin, saeedm, leon, f.fainelli

On Mon, 10 Jun 2019 11:09:19 -0600, David Ahern wrote:
> On 6/4/19 7:44 AM, Jiri Pirko wrote:
> > diff --git a/man/man8/devlink-dev.8 b/man/man8/devlink-dev.8
> > index 1804463b2321..1021ee8d064c 100644
> > --- a/man/man8/devlink-dev.8
> > +++ b/man/man8/devlink-dev.8
> > @@ -244,6 +244,17 @@ Sets the parameter internal_error_reset of specified devlink device to true.
> >  devlink dev reload pci/0000:01:00.0
> >  .RS 4
> >  Performs hot reload of specified devlink device.
> > +.RE
> > +.PP
> > +devlink dev flash pci/0000:01:00.0 file firmware.bin
> > +.RS 4
> > +Flashes the specified devlink device with provided firmware file name. If the driver supports it, user gets updates about the flash status. For example:
> > +.br
> > +Preparing to flash
> > +.br
> > +Flashing 100%
> > +.br
> > +Flashing done
> >  
> >  .SH SEE ALSO
> >  .BR devlink (8),  
> 
> something is missing here from a user perspective at least:
> 
> root@mlx-2700-05:~# ./devlink dev
> pci/0000:03:00.0
> 
> root@mlx-2700-05:~# ./devlink dev flash pci/0000:03:00.0 file
> /lib/firmware/mellanox/mlxsw_spectrum-13.2000.1122.mfa2
> devlink answers: No such file or directory
> 
> root@mlx-2700-05:~# ls -l
> /lib/firmware/mellanox/mlxsw_spectrum-13.2000.1122.mfa2
> -rw-r--r-- 1 cumulus 1001 994184 May 14 22:44
> /lib/firmware/mellanox/mlxsw_spectrum-13.2000.1122.mfa2
> 
> 
> Why the 'no such file' response when the file exists?

I think the FW loader prepends /lib/firmware to the path (there is a
CONFIG_ for the search paths, and / is usually not on it).  Perhaps try:

./devlink dev flash pci/0000:03:00.0 file mellanox/mlxsw_spectrum-13.2000.1122.mfa2

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

* Re: [patch net-next v3 3/3] devlink: implement flash status monitoring
  2019-06-10 17:24     ` Jakub Kicinski
@ 2019-06-10 17:30       ` David Ahern
  2019-06-10 17:47         ` Jakub Kicinski
  0 siblings, 1 reply; 24+ messages in thread
From: David Ahern @ 2019-06-10 17:30 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Jiri Pirko, netdev, davem, mlxsw, sthemmin, saeedm, leon, f.fainelli

On 6/10/19 11:24 AM, Jakub Kicinski wrote:
> On Mon, 10 Jun 2019 11:09:19 -0600, David Ahern wrote:
>> On 6/4/19 7:44 AM, Jiri Pirko wrote:
>>> diff --git a/man/man8/devlink-dev.8 b/man/man8/devlink-dev.8
>>> index 1804463b2321..1021ee8d064c 100644
>>> --- a/man/man8/devlink-dev.8
>>> +++ b/man/man8/devlink-dev.8
>>> @@ -244,6 +244,17 @@ Sets the parameter internal_error_reset of specified devlink device to true.
>>>  devlink dev reload pci/0000:01:00.0
>>>  .RS 4
>>>  Performs hot reload of specified devlink device.
>>> +.RE
>>> +.PP
>>> +devlink dev flash pci/0000:01:00.0 file firmware.bin
>>> +.RS 4
>>> +Flashes the specified devlink device with provided firmware file name. If the driver supports it, user gets updates about the flash status. For example:
>>> +.br
>>> +Preparing to flash
>>> +.br
>>> +Flashing 100%
>>> +.br
>>> +Flashing done
>>>  
>>>  .SH SEE ALSO
>>>  .BR devlink (8),  
>>
>> something is missing here from a user perspective at least:
>>
>> root@mlx-2700-05:~# ./devlink dev
>> pci/0000:03:00.0
>>
>> root@mlx-2700-05:~# ./devlink dev flash pci/0000:03:00.0 file
>> /lib/firmware/mellanox/mlxsw_spectrum-13.2000.1122.mfa2
>> devlink answers: No such file or directory
>>
>> root@mlx-2700-05:~# ls -l
>> /lib/firmware/mellanox/mlxsw_spectrum-13.2000.1122.mfa2
>> -rw-r--r-- 1 cumulus 1001 994184 May 14 22:44
>> /lib/firmware/mellanox/mlxsw_spectrum-13.2000.1122.mfa2
>>
>>
>> Why the 'no such file' response when the file exists?
> 
> I think the FW loader prepends /lib/firmware to the path (there is a
> CONFIG_ for the search paths, and / is usually not on it).  Perhaps try:
> 
> ./devlink dev flash pci/0000:03:00.0 file mellanox/mlxsw_spectrum-13.2000.1122.mfa2
> 

that worked, but if the user specifies fullpath that is confusing. So at
a minimum the documentation needs to be clear about the paths.

But, why the path limitation? why not allow a user to load a file from
any directory? For mlxsw at least the file in /lib/firmware will be
loaded automagically, so forcing the file to always be in /lib/firmware
seems counterintuitive when using a command to specify the file to load.

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

* Re: [patch net-next v3 3/3] devlink: implement flash status monitoring
  2019-06-10 17:30       ` David Ahern
@ 2019-06-10 17:47         ` Jakub Kicinski
  2019-06-10 21:56           ` David Ahern
  0 siblings, 1 reply; 24+ messages in thread
From: Jakub Kicinski @ 2019-06-10 17:47 UTC (permalink / raw)
  To: David Ahern
  Cc: Jiri Pirko, netdev, davem, mlxsw, sthemmin, saeedm, leon, f.fainelli

On Mon, 10 Jun 2019 11:30:24 -0600, David Ahern wrote:
> On 6/10/19 11:24 AM, Jakub Kicinski wrote:
> > On Mon, 10 Jun 2019 11:09:19 -0600, David Ahern wrote:  
> >> On 6/4/19 7:44 AM, Jiri Pirko wrote:  
> >>> diff --git a/man/man8/devlink-dev.8 b/man/man8/devlink-dev.8
> >>> index 1804463b2321..1021ee8d064c 100644
> >>> --- a/man/man8/devlink-dev.8
> >>> +++ b/man/man8/devlink-dev.8
> >>> @@ -244,6 +244,17 @@ Sets the parameter internal_error_reset of specified devlink device to true.
> >>>  devlink dev reload pci/0000:01:00.0
> >>>  .RS 4
> >>>  Performs hot reload of specified devlink device.
> >>> +.RE
> >>> +.PP
> >>> +devlink dev flash pci/0000:01:00.0 file firmware.bin
> >>> +.RS 4
> >>> +Flashes the specified devlink device with provided firmware file name. If the driver supports it, user gets updates about the flash status. For example:
> >>> +.br
> >>> +Preparing to flash
> >>> +.br
> >>> +Flashing 100%
> >>> +.br
> >>> +Flashing done
> >>>  
> >>>  .SH SEE ALSO
> >>>  .BR devlink (8),    
> >>
> >> something is missing here from a user perspective at least:
> >>
> >> root@mlx-2700-05:~# ./devlink dev
> >> pci/0000:03:00.0
> >>
> >> root@mlx-2700-05:~# ./devlink dev flash pci/0000:03:00.0 file
> >> /lib/firmware/mellanox/mlxsw_spectrum-13.2000.1122.mfa2
> >> devlink answers: No such file or directory
> >>
> >> root@mlx-2700-05:~# ls -l
> >> /lib/firmware/mellanox/mlxsw_spectrum-13.2000.1122.mfa2
> >> -rw-r--r-- 1 cumulus 1001 994184 May 14 22:44
> >> /lib/firmware/mellanox/mlxsw_spectrum-13.2000.1122.mfa2
> >>
> >>
> >> Why the 'no such file' response when the file exists?  
> > 
> > I think the FW loader prepends /lib/firmware to the path (there is a
> > CONFIG_ for the search paths, and / is usually not on it).  Perhaps try:
> > 
> > ./devlink dev flash pci/0000:03:00.0 file mellanox/mlxsw_spectrum-13.2000.1122.mfa2
> >   
> 
> that worked, but if the user specifies fullpath that is confusing. So at
> a minimum the documentation needs to be clear about the paths.
> 
> But, why the path limitation? why not allow a user to load a file from
> any directory? For mlxsw at least the file in /lib/firmware will be
> loaded automagically, so forcing the file to always be in /lib/firmware
> seems counterintuitive when using a command to specify the file to load.

It's the kernel that does this, the request_firmware() API.  It's
documented in both devlink's and ethtool's API.  I was initially
intending to use the file request API directly in devlink, but because
of the requirement to keep compatibility with ethtool that was a no go.

FWIW you can load from any directory, just prefix the file name
with ../../ to get out of /lib/firmware.

I guess we could add some logic into devlink user space to detect that
user does not know about this quirk and fix up the path for them.. 🤔

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

* Re: [patch net-next v3 3/3] devlink: implement flash status monitoring
  2019-06-10 17:47         ` Jakub Kicinski
@ 2019-06-10 21:56           ` David Ahern
  2019-06-10 22:06             ` Jakub Kicinski
  0 siblings, 1 reply; 24+ messages in thread
From: David Ahern @ 2019-06-10 21:56 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Jiri Pirko, netdev, davem, mlxsw, sthemmin, saeedm, leon, f.fainelli

On 6/10/19 11:47 AM, Jakub Kicinski wrote:
> It's the kernel that does this, the request_firmware() API.  It's
> documented in both devlink's and ethtool's API.  I was initially
> intending to use the file request API directly in devlink, but because
> of the requirement to keep compatibility with ethtool that was a no go.
> 
> FWIW you can load from any directory, just prefix the file name
> with ../../ to get out of /lib/firmware.
> 
> I guess we could add some logic into devlink user space to detect that
> user does not know about this quirk and fix up the path for them.. 🤔

If the user can not load a file based on an arbitrary path, what is the
point of the option in the devlink command? You might as well just have
the driver use the firmware interface.

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

* Re: [patch net-next v3 3/3] devlink: implement flash status monitoring
  2019-06-10 21:56           ` David Ahern
@ 2019-06-10 22:06             ` Jakub Kicinski
  0 siblings, 0 replies; 24+ messages in thread
From: Jakub Kicinski @ 2019-06-10 22:06 UTC (permalink / raw)
  To: David Ahern
  Cc: Jiri Pirko, netdev, davem, mlxsw, sthemmin, saeedm, leon, f.fainelli

On Mon, 10 Jun 2019 15:56:00 -0600, David Ahern wrote:
> On 6/10/19 11:47 AM, Jakub Kicinski wrote:
> > It's the kernel that does this, the request_firmware() API.  It's
> > documented in both devlink's and ethtool's API.  I was initially
> > intending to use the file request API directly in devlink, but because
> > of the requirement to keep compatibility with ethtool that was a no go.
> > 
> > FWIW you can load from any directory, just prefix the file name
> > with ../../ to get out of /lib/firmware.
> > 
> > I guess we could add some logic into devlink user space to detect that
> > user does not know about this quirk and fix up the path for them.. 🤔  
> 
> If the user can not load a file based on an arbitrary path, what is the
> point of the option in the devlink command? You might as well just have
> the driver use the firmware interface.

This may be a question about mlxsw quirks.  Traditionally drivers don't
flash firmware on probe.  Devlink/ethtool interface is for updating
flash contents, while probe may load FW directly into SRAM for devices
which don't store firmware on flash (e.g. most WiFi cards).

Also - devlink _can_ load from arbitrary paths.  User just has to assume
getcwd() == "/lib/firmware".  Probe has a hard coded file name it 
will try to load.

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

end of thread, other threads:[~2019-06-10 22:06 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-04 13:40 [patch net-next v3 0/8] expose flash update status to user Jiri Pirko
2019-06-04 13:40 ` [patch net-next v3 1/8] mlxsw: Move firmware flash implementation to devlink Jiri Pirko
2019-06-04 13:40 ` [patch net-next v3 2/8] mlx5: " Jiri Pirko
2019-06-04 18:40   ` Saeed Mahameed
2019-06-04 13:40 ` [patch net-next v3 3/8] mlxfw: Propagate error messages through extack Jiri Pirko
2019-06-04 13:40 ` [patch net-next v3 4/8] devlink: allow driver to update progress of flash update Jiri Pirko
2019-06-04 13:40 ` [patch net-next v3 5/8] mlxfw: Introduce status_notify op and call it to notify about the status Jiri Pirko
2019-06-04 13:40 ` [patch net-next v3 6/8] mlxsw: Implement flash update status notifications Jiri Pirko
2019-06-04 13:40 ` [patch net-next v3 7/8] netdevsim: implement fake flash updating with notifications Jiri Pirko
2019-06-04 17:54   ` Jakub Kicinski
2019-06-04 13:40 ` [patch net-next v3 8/8] selftests: add basic netdevsim devlink flash testing Jiri Pirko
2019-06-04 17:55   ` Jakub Kicinski
2019-06-04 13:44 ` [patch net-next v3 1/3] header update Jiri Pirko
2019-06-04 13:54   ` Jiri Pirko
2019-06-04 13:44 ` [patch net-next v3 2/3] devlink: implement flash update status monitoring Jiri Pirko
2019-06-04 13:44 ` [patch net-next v3 3/3] devlink: implement flash " Jiri Pirko
2019-06-10 17:09   ` David Ahern
2019-06-10 17:24     ` Jakub Kicinski
2019-06-10 17:30       ` David Ahern
2019-06-10 17:47         ` Jakub Kicinski
2019-06-10 21:56           ` David Ahern
2019-06-10 22:06             ` Jakub Kicinski
2019-06-04 15:09 ` [patch net-next v3 0/8] expose flash update status to user Alexei Starovoitov
2019-06-04 21:21 ` David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.