// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 /* Copyright (c) 2017-2019 Mellanox Technologies. All rights reserved */ #define pr_fmt(fmt) … #include <linux/kernel.h> #include <linux/module.h> #include <linux/netlink.h> #include <linux/vmalloc.h> #include <linux/xz.h> #include "mlxfw_mfa2.h" #include "mlxfw_mfa2_file.h" #include "mlxfw_mfa2_tlv.h" #include "mlxfw_mfa2_format.h" #include "mlxfw_mfa2_tlv_multi.h" /* MFA2 FILE * +----------------------------------+ * | MFA2 finger print | * +----------------------------------+ * | package descriptor multi_tlv | * | +------------------------------+ | +-----------------+ * | | package descriptor tlv +-----> |num_devices=n | * | +------------------------------+ | |num_components=m | * +----------------------------------+ |CB offset | * | device descriptor multi_tlv | |... | * | +------------------------------+ | | | * | | PSID tlv | | +-----------------+ * | +------------------------------+ | * | | component index tlv | | * | +------------------------------+ | * +----------------------------------+ * | component descriptor multi_tlv | * | +------------------------------+ | +-----------------+ * | | component descriptor tlv +-----> |Among others: | * | +------------------------------+ | |CB offset=o | * +----------------------------------+ |comp index=i | * | | |... | * | | | | * | | +-----------------+ * | COMPONENT BLOCK (CB) | * | | * | | * | | * +----------------------------------+ * * On the top level, an MFA2 file contains: * - Fingerprint * - Several multi_tlvs (TLVs of type MLXFW_MFA2_TLV_MULTI, as defined in * mlxfw_mfa2_format.h) * - Compresses content block * * The first multi_tlv * ------------------- * The first multi TLV is treated as package descriptor, and expected to have a * first TLV child of type MLXFW_MFA2_TLV_PACKAGE_DESCRIPTOR which contains all * the global information needed to parse the file. Among others, it contains * the number of device descriptors and component descriptor following this * multi TLV. * * The device descriptor multi_tlv * ------------------------------- * The multi TLVs following the package descriptor are treated as device * descriptor, and are expected to have the following children: * - PSID TLV child of type MLXFW_MFA2_TLV_PSID containing that device PSID. * - Component index of type MLXFW_MFA2_TLV_COMPONENT_PTR that contains that * device component index. * * The component descriptor multi_tlv * ---------------------------------- * The multi TLVs following the device descriptor multi TLVs are treated as * component descriptor, and are expected to have a first child of type * MLXFW_MFA2_TLV_COMPONENT_DESCRIPTOR that contains mostly the component index, * needed for the flash process and the offset to the binary within the * component block. */ static const u8 mlxfw_mfa2_fingerprint[] = …; static const int mlxfw_mfa2_fingerprint_len = …; static const u8 mlxfw_mfa2_comp_magic[] = …; static const int mlxfw_mfa2_comp_magic_len = …; bool mlxfw_mfa2_check(const struct firmware *fw) { … } static bool mlxfw_mfa2_tlv_multi_validate(const struct mlxfw_mfa2_file *mfa2_file, const struct mlxfw_mfa2_tlv_multi *multi) { … } static bool mlxfw_mfa2_file_dev_validate(const struct mlxfw_mfa2_file *mfa2_file, const struct mlxfw_mfa2_tlv *dev_tlv, u16 dev_idx) { … } static bool mlxfw_mfa2_file_comp_validate(const struct mlxfw_mfa2_file *mfa2_file, const struct mlxfw_mfa2_tlv *comp_tlv, u16 comp_idx) { … } static bool mlxfw_mfa2_file_validate(const struct mlxfw_mfa2_file *mfa2_file) { … } struct mlxfw_mfa2_file *mlxfw_mfa2_file_init(const struct firmware *fw) { … } static const struct mlxfw_mfa2_tlv_multi * mlxfw_mfa2_tlv_dev_get(const struct mlxfw_mfa2_file *mfa2_file, const char *psid, u16 psid_size) { … } int mlxfw_mfa2_file_component_count(const struct mlxfw_mfa2_file *mfa2_file, const char *psid, u32 psid_size, u32 *p_count) { … } static int mlxfw_mfa2_xz_dec_run(struct xz_dec *xz_dec, struct xz_buf *xz_buf, bool *finished) { … } static int mlxfw_mfa2_file_cb_offset_xz(const struct mlxfw_mfa2_file *mfa2_file, off_t off, size_t size, u8 *buf) { … } static const struct mlxfw_mfa2_tlv_component_descriptor * mlxfw_mfa2_file_component_tlv_get(const struct mlxfw_mfa2_file *mfa2_file, u16 comp_index) { … } struct mlxfw_mfa2_comp_data { … }; static const struct mlxfw_mfa2_tlv_component_descriptor * mlxfw_mfa2_file_component_find(const struct mlxfw_mfa2_file *mfa2_file, const char *psid, int psid_size, int component_index) { … } struct mlxfw_mfa2_component * mlxfw_mfa2_file_component_get(const struct mlxfw_mfa2_file *mfa2_file, const char *psid, int psid_size, int component_index) { … } void mlxfw_mfa2_file_component_put(struct mlxfw_mfa2_component *comp) { … } void mlxfw_mfa2_file_fini(struct mlxfw_mfa2_file *mfa2_file) { … }