]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
net/mlx5e: Support the flash device ethtool callback
authorOr Gerlitz <ogerlitz@mellanox.com>
Tue, 18 Apr 2017 14:48:46 +0000 (17:48 +0300)
committerSaeed Mahameed <saeedm@mellanox.com>
Thu, 22 Jun 2017 11:30:13 +0000 (14:30 +0300)
This callback further invokes the mlxfw module to flash the new
firmware file to the device.

As the firmware flash process takes about 20 seconds and ethtool
takes the rtnl lock during the flash_device callback, we release
the rtnl lock at the beginning of the flash process and take it
again before leaving the callback.

This way, rtnl is not held during the process. To make sure the
device does not get deleted while being flashed, we take a
reference to it before releasing rtnl lock.

Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Yotam Gigi <yotamg@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c

index 709f500ef16f2c4c565162425e1d4cf074113bf6..eef0a50e2388e812f4d760378a53660bb6c76a94 100644 (file)
@@ -1060,6 +1060,8 @@ int mlx5e_ethtool_set_coalesce(struct mlx5e_priv *priv,
                               struct ethtool_coalesce *coal);
 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);
 
 /* mlx5e generic netdev management API */
 struct net_device*
index 169435d8aa1e50e70036d9cc1ba33b95ce999638..16b1e96a7050bbfbb91e21781691f48adfa1fec0 100644 (file)
@@ -1795,6 +1795,40 @@ static int mlx5e_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
        return err;
 }
 
+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);
+}
+
 const struct ethtool_ops mlx5e_ethtool_ops = {
        .get_drvinfo       = mlx5e_get_drvinfo,
        .get_link          = ethtool_op_get_link,
@@ -1815,6 +1849,7 @@ const struct ethtool_ops mlx5e_ethtool_ops = {
        .set_rxfh          = mlx5e_set_rxfh,
        .get_rxnfc         = mlx5e_get_rxnfc,
        .set_rxnfc         = mlx5e_set_rxnfc,
+       .flash_device      = mlx5e_flash_device,
        .get_tunable       = mlx5e_get_tunable,
        .set_tunable       = mlx5e_set_tunable,
        .get_pauseparam    = mlx5e_get_pauseparam,