Commit 4fd310c7 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'implement-dev-info-and-dev-flash-for-line-cards'

Jiri Pirko says:

====================
Implement dev info and dev flash for line cards

This patchset implements two features:
1) "devlink dev info" is exposed for line card (patches 6-9)
2) "devlink dev flash" is implemented for line card gearbox
   flashing (patch 10)

For every line card, "a nested" auxiliary device is created which
allows to bind the features mentioned above (patch 4).

The relationship between line card and its auxiliary dev devlink
is carried over extra line card netlink attribute (patches 3 and 5).

The first patch removes devlink_mutex from devlink_register/unregister()
which eliminates possible deadlock during devlink reload command. The
second patchset follows up with putting net pointer check into new
helper.

Examples:

$ devlink lc show pci/0000:01:00.0 lc 1
pci/0000:01:00.0:
  lc 1 state active type 16x100G nested_devlink auxiliary/mlxsw_core.lc.0
    supported_types:
       16x100G

$ devlink dev show auxiliary/mlxsw_core.lc.0
auxiliary/mlxsw_core.lc.0

$ devlink dev info auxiliary/mlxsw_core.lc.0
auxiliary/mlxsw_core.lc.0:
  versions:
      fixed:
        hw.revision 0
        fw.psid MT_0000000749
      running:
        ini.version 4
        fw 19.2010.1312

$ devlink dev flash auxiliary/mlxsw_core.lc.0 file mellanox/fw-AGB-rel-19_2010_1312-022-EVB.mfa2
====================

Link: https://lore.kernel.org/r/20220725082925.366455-1-jiri@resnulli.us


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 35d099da 949c84f0
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -58,6 +58,30 @@ The ``mlxsw`` driver reports the following versions
     - running
     - Three digit firmware version

Line card auxiliary device info versions
========================================

The ``mlxsw`` driver reports the following versions for line card auxiliary device

.. list-table:: devlink info versions implemented
   :widths: 5 5 90

   * - Name
     - Type
     - Description
   * - ``hw.revision``
     - fixed
     - The hardware revision for this line card
   * - ``ini.version``
     - running
     - Version of line card INI loaded
   * - ``fw.psid``
     - fixed
     - Line card device PSID
   * - ``fw.version``
     - running
     - Three digit firmware version of line card device

Driver-specific Traps
=====================

+1 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ config MLXSW_CORE
	tristate "Mellanox Technologies Switch ASICs support"
	select NET_DEVLINK
	select MLXFW
	select AUXILIARY_BUS
	help
	  This driver supports Mellanox Technologies Switch ASICs family.

+1 −1
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
obj-$(CONFIG_MLXSW_CORE)	+= mlxsw_core.o
mlxsw_core-objs			:= core.o core_acl_flex_keys.o \
				   core_acl_flex_actions.o core_env.o \
				   core_linecards.o
				   core_linecards.o core_linecard_dev.o
mlxsw_core-$(CONFIG_MLXSW_CORE_HWMON) += core_hwmon.o
mlxsw_core-$(CONFIG_MLXSW_CORE_THERMAL) += core_thermal.o
obj-$(CONFIG_MLXSW_PCI)		+= mlxsw_pci.o
+32 −12
Original line number Diff line number Diff line
@@ -951,6 +951,20 @@ static struct mlxsw_driver *mlxsw_core_driver_get(const char *kind)
	return mlxsw_driver;
}

int mlxsw_core_fw_flash(struct mlxsw_core *mlxsw_core,
			struct mlxfw_dev *mlxfw_dev,
			const struct firmware *firmware,
			struct netlink_ext_ack *extack)
{
	int err;

	mlxsw_core->fw_flash_in_progress = true;
	err = mlxfw_firmware_flash(mlxfw_dev, firmware, extack);
	mlxsw_core->fw_flash_in_progress = false;

	return err;
}

struct mlxsw_core_fw_info {
	struct mlxfw_dev mlxfw_dev;
	struct mlxsw_core *mlxsw_core;
@@ -1105,7 +1119,8 @@ static const struct mlxfw_dev_ops mlxsw_core_fw_mlxsw_dev_ops = {
	.fsm_release		= mlxsw_core_fw_fsm_release,
};

static int mlxsw_core_fw_flash(struct mlxsw_core *mlxsw_core, const struct firmware *firmware,
static int mlxsw_core_dev_fw_flash(struct mlxsw_core *mlxsw_core,
				   const struct firmware *firmware,
				   struct netlink_ext_ack *extack)
{
	struct mlxsw_core_fw_info mlxsw_core_fw_info = {
@@ -1117,13 +1132,9 @@ static int mlxsw_core_fw_flash(struct mlxsw_core *mlxsw_core, const struct firmw
		},
		.mlxsw_core = mlxsw_core
	};
	int err;

	mlxsw_core->fw_flash_in_progress = true;
	err = mlxfw_firmware_flash(&mlxsw_core_fw_info.mlxfw_dev, firmware, extack);
	mlxsw_core->fw_flash_in_progress = false;

	return err;
	return mlxsw_core_fw_flash(mlxsw_core, &mlxsw_core_fw_info.mlxfw_dev,
				   firmware, extack);
}

static int mlxsw_core_fw_rev_validate(struct mlxsw_core *mlxsw_core,
@@ -1169,7 +1180,7 @@ static int mlxsw_core_fw_rev_validate(struct mlxsw_core *mlxsw_core,
		return err;
	}

	err = mlxsw_core_fw_flash(mlxsw_core, firmware, NULL);
	err = mlxsw_core_dev_fw_flash(mlxsw_core, firmware, NULL);
	release_firmware(firmware);
	if (err)
		dev_err(mlxsw_bus_info->dev, "Could not upgrade firmware\n");
@@ -1187,7 +1198,7 @@ static int mlxsw_core_fw_flash_update(struct mlxsw_core *mlxsw_core,
				      struct devlink_flash_update_params *params,
				      struct netlink_ext_ack *extack)
{
	return mlxsw_core_fw_flash(mlxsw_core, params->fw, extack);
	return mlxsw_core_dev_fw_flash(mlxsw_core, params->fw, extack);
}

static int mlxsw_core_devlink_param_fw_load_policy_validate(struct devlink *devlink, u32 id,
@@ -3334,9 +3345,15 @@ static int __init mlxsw_core_module_init(void)
{
	int err;

	err = mlxsw_linecard_driver_register();
	if (err)
		return err;

	mlxsw_wq = alloc_workqueue(mlxsw_core_driver_name, 0, 0);
	if (!mlxsw_wq)
		return -ENOMEM;
	if (!mlxsw_wq) {
		err = -ENOMEM;
		goto err_alloc_workqueue;
	}
	mlxsw_owq = alloc_ordered_workqueue("%s_ordered", 0,
					    mlxsw_core_driver_name);
	if (!mlxsw_owq) {
@@ -3347,6 +3364,8 @@ static int __init mlxsw_core_module_init(void)

err_alloc_ordered_workqueue:
	destroy_workqueue(mlxsw_wq);
err_alloc_workqueue:
	mlxsw_linecard_driver_unregister();
	return err;
}

@@ -3354,6 +3373,7 @@ static void __exit mlxsw_core_module_exit(void)
{
	destroy_workqueue(mlxsw_owq);
	destroy_workqueue(mlxsw_wq);
	mlxsw_linecard_driver_unregister();
}

module_init(mlxsw_core_module_init);
+35 −0
Original line number Diff line number Diff line
@@ -12,12 +12,14 @@
#include <linux/skbuff.h>
#include <linux/workqueue.h>
#include <linux/net_namespace.h>
#include <linux/auxiliary_bus.h>
#include <net/devlink.h>

#include "trap.h"
#include "reg.h"
#include "cmd.h"
#include "resources.h"
#include "../mlxfw/mlxfw.h"

enum mlxsw_core_resource_id {
	MLXSW_CORE_RESOURCE_PORTS = 1,
@@ -47,6 +49,11 @@ mlxsw_core_fw_rev_minor_subminor_validate(const struct mlxsw_fw_rev *rev,
int mlxsw_core_driver_register(struct mlxsw_driver *mlxsw_driver);
void mlxsw_core_driver_unregister(struct mlxsw_driver *mlxsw_driver);

int mlxsw_core_fw_flash(struct mlxsw_core *mlxsw_core,
			struct mlxfw_dev *mlxfw_dev,
			const struct firmware *firmware,
			struct netlink_ext_ack *extack);

int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
				   const struct mlxsw_bus *mlxsw_bus,
				   void *bus_priv, bool reload,
@@ -563,6 +570,15 @@ enum mlxsw_linecard_status_event_type {
	MLXSW_LINECARD_STATUS_EVENT_TYPE_UNPROVISION,
};

struct mlxsw_linecard_bdev;

struct mlxsw_linecard_device_info {
	u16 fw_major;
	u16 fw_minor;
	u16 fw_sub_minor;
	char psid[MLXSW_REG_MGIR_FW_INFO_PSID_SIZE];
};

struct mlxsw_linecard {
	u8 slot_index;
	struct mlxsw_linecards *linecards;
@@ -577,6 +593,11 @@ struct mlxsw_linecard {
	   active:1;
	u16 hw_revision;
	u16 ini_version;
	struct mlxsw_linecard_bdev *bdev;
	struct {
		struct mlxsw_linecard_device_info info;
		u8 index;
	} device;
};

struct mlxsw_linecard_types_info;
@@ -597,6 +618,14 @@ mlxsw_linecard_get(struct mlxsw_linecards *linecards, u8 slot_index)
	return &linecards->linecards[slot_index - 1];
}

int mlxsw_linecard_devlink_info_get(struct mlxsw_linecard *linecard,
				    struct devlink_info_req *req,
				    struct netlink_ext_ack *extack);
int mlxsw_linecard_flash_update(struct devlink *linecard_devlink,
				struct mlxsw_linecard *linecard,
				const struct firmware *firmware,
				struct netlink_ext_ack *extack);

int mlxsw_linecards_init(struct mlxsw_core *mlxsw_core,
			 const struct mlxsw_bus_info *bus_info);
void mlxsw_linecards_fini(struct mlxsw_core *mlxsw_core);
@@ -616,4 +645,10 @@ void mlxsw_linecards_event_ops_unregister(struct mlxsw_core *mlxsw_core,
					  struct mlxsw_linecards_event_ops *ops,
					  void *priv);

int mlxsw_linecard_bdev_add(struct mlxsw_linecard *linecard);
void mlxsw_linecard_bdev_del(struct mlxsw_linecard *linecard);

int mlxsw_linecard_driver_register(void);
void mlxsw_linecard_driver_unregister(void);

#endif
Loading