@@ -71,7 +71,6 @@ config RPMSG_WWAN_CTRL
config IOSM
tristate "IOSM Driver for Intel M.2 WWAN Device"
depends on INTEL_IOMMU
- select NET_DEVLINK
help
This driver enables Intel M.2 WWAN Device communication.
@@ -18,9 +18,6 @@ iosm-y = \
iosm_ipc_protocol.o \
iosm_ipc_protocol_ops.o \
iosm_ipc_mux.o \
- iosm_ipc_mux_codec.o \
- iosm_ipc_devlink.o \
- iosm_ipc_flash.o \
- iosm_ipc_coredump.o
+ iosm_ipc_mux_codec.o
obj-$(CONFIG_IOSM) := iosm.o
@@ -8,7 +8,7 @@
#include "iosm_ipc_chnl_cfg.h"
/* Max. sizes of a downlink buffers */
-#define IPC_MEM_MAX_DL_FLASH_BUF_SIZE (64 * 1024)
+#define IPC_MEM_MAX_DL_FLASH_BUF_SIZE (16 * 1024)
#define IPC_MEM_MAX_DL_LOOPBACK_SIZE (1 * 1024 * 1024)
#define IPC_MEM_MAX_DL_AT_BUF_SIZE 2048
#define IPC_MEM_MAX_DL_RPC_BUF_SIZE (32 * 1024)
@@ -60,10 +60,6 @@ static struct ipc_chnl_cfg modem_cfg[] = {
{ IPC_MEM_CTRL_CHL_ID_6, IPC_MEM_PIPE_12, IPC_MEM_PIPE_13,
IPC_MEM_MAX_TDS_MBIM, IPC_MEM_MAX_TDS_MBIM,
IPC_MEM_MAX_DL_MBIM_BUF_SIZE, WWAN_PORT_MBIM },
- /* Flash Channel/Coredump Channel */
- { IPC_MEM_CTRL_CHL_ID_7, IPC_MEM_PIPE_0, IPC_MEM_PIPE_1,
- IPC_MEM_MAX_TDS_FLASH_UL, IPC_MEM_MAX_TDS_FLASH_DL,
- IPC_MEM_MAX_DL_FLASH_BUF_SIZE, WWAN_PORT_UNKNOWN },
};
int ipc_chnl_cfg_get(struct ipc_chnl_cfg *chnl_cfg, int index)
@@ -23,7 +23,6 @@ enum ipc_channel_id {
IPC_MEM_CTRL_CHL_ID_4,
IPC_MEM_CTRL_CHL_ID_5,
IPC_MEM_CTRL_CHL_ID_6,
- IPC_MEM_CTRL_CHL_ID_7,
};
/**
deleted file mode 100644
@@ -1,110 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2020-2021 Intel Corporation.
- */
-
-#include "iosm_ipc_coredump.h"
-
-/* Collect coredump data from modem */
-int ipc_coredump_collect(struct iosm_devlink *devlink, u8 **data, int entry,
- u32 region_size)
-{
- int ret, bytes_to_read, bytes_read = 0, i = 0;
- s32 remaining;
- u8 *data_ptr;
-
- data_ptr = vmalloc(region_size);
- if (!data_ptr)
- return -ENOMEM;
-
- remaining = devlink->cd_file_info[entry].actual_size;
- ret = ipc_devlink_send_cmd(devlink, rpsi_cmd_coredump_get, entry);
- if (ret) {
- dev_err(devlink->dev, "Send coredump_get cmd failed");
- goto get_cd_fail;
- }
- while (remaining > 0) {
- bytes_to_read = min(remaining, MAX_DATA_SIZE);
- bytes_read = 0;
- ret = ipc_imem_sys_devlink_read(devlink, data_ptr + i,
- bytes_to_read, &bytes_read);
- if (ret) {
- dev_err(devlink->dev, "CD data read failed");
- goto get_cd_fail;
- }
- remaining -= bytes_read;
- i += bytes_read;
- }
-
- *data = data_ptr;
-
- return ret;
-get_cd_fail:
- vfree(data_ptr);
- return ret;
-}
-
-/* Get coredump list to be collected from modem */
-int ipc_coredump_get_list(struct iosm_devlink *devlink, u16 cmd)
-{
- u32 byte_read, num_entries, file_size;
- struct iosm_cd_table *cd_table;
- u8 size[MAX_SIZE_LEN], i;
- char *filename;
- int ret = 0;
-
- cd_table = kzalloc(MAX_CD_LIST_SIZE, GFP_KERNEL);
- if (!cd_table) {
- ret = -ENOMEM;
- goto cd_init_fail;
- }
-
- ret = ipc_devlink_send_cmd(devlink, cmd, MAX_CD_LIST_SIZE);
- if (ret) {
- dev_err(devlink->dev, "rpsi_cmd_coredump_start failed");
- goto cd_init_fail;
- }
-
- ret = ipc_imem_sys_devlink_read(devlink, (u8 *)cd_table,
- MAX_CD_LIST_SIZE, &byte_read);
- if (ret) {
- dev_err(devlink->dev, "Coredump data is invalid");
- goto cd_init_fail;
- }
-
- if (byte_read != MAX_CD_LIST_SIZE)
- goto cd_init_fail;
-
- if (cmd == rpsi_cmd_coredump_start) {
- num_entries = le32_to_cpu(cd_table->list.num_entries);
- if (num_entries == 0 || num_entries > IOSM_NOF_CD_REGION) {
- ret = -EINVAL;
- goto cd_init_fail;
- }
-
- for (i = 0; i < num_entries; i++) {
- file_size = le32_to_cpu(cd_table->list.entry[i].size);
- filename = cd_table->list.entry[i].filename;
-
- if (file_size > devlink->cd_file_info[i].default_size) {
- ret = -EINVAL;
- goto cd_init_fail;
- }
-
- devlink->cd_file_info[i].actual_size = file_size;
- dev_dbg(devlink->dev, "file: %s actual size %d",
- filename, file_size);
- devlink_flash_update_status_notify(devlink->devlink_ctx,
- filename,
- "FILENAME", 0, 0);
- snprintf(size, sizeof(size), "%d", file_size);
- devlink_flash_update_status_notify(devlink->devlink_ctx,
- size, "FILE SIZE",
- 0, 0);
- }
- }
-
-cd_init_fail:
- kfree(cd_table);
- return ret;
-}
deleted file mode 100644
@@ -1,75 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only
- *
- * Copyright (C) 2020-2021 Intel Corporation.
- */
-
-#ifndef _IOSM_IPC_COREDUMP_H_
-#define _IOSM_IPC_COREDUMP_H_
-
-#include "iosm_ipc_devlink.h"
-
-/* Max number of bytes to receive for Coredump list structure */
-#define MAX_CD_LIST_SIZE 0x1000
-
-/* Max buffer allocated to receive coredump data */
-#define MAX_DATA_SIZE 0x00010000
-
-/* Max number of file entries */
-#define MAX_NOF_ENTRY 256
-
-/* Max length */
-#define MAX_SIZE_LEN 32
-
-/**
- * struct iosm_cd_list_entry - Structure to hold coredump file info.
- * @size: Number of bytes for the entry
- * @filename: Coredump filename to be generated on host
- */
-struct iosm_cd_list_entry {
- __le32 size;
- char filename[IOSM_MAX_FILENAME_LEN];
-} __packed;
-
-/**
- * struct iosm_cd_list - Structure to hold list of coredump files
- * to be collected.
- * @num_entries: Number of entries to be received
- * @entry: Contains File info
- */
-struct iosm_cd_list {
- __le32 num_entries;
- struct iosm_cd_list_entry entry[MAX_NOF_ENTRY];
-} __packed;
-
-/**
- * struct iosm_cd_table - Common Coredump table
- * @version: Version of coredump structure
- * @list: Coredump list structure
- */
-struct iosm_cd_table {
- __le32 version;
- struct iosm_cd_list list;
-} __packed;
-
-/**
- * ipc_coredump_collect - To collect coredump
- * @devlink: Pointer to devlink instance.
- * @data: Pointer to snapshot
- * @entry: ID of requested snapshot
- * @region_size: Region size
- *
- * Returns: 0 on success, error on failure
- */
-int ipc_coredump_collect(struct iosm_devlink *devlink, u8 **data, int entry,
- u32 region_size);
-
-/**
- * ipc_coredump_get_list - Get coredump list
- * @devlink: Pointer to devlink instance.
- * @cmd: RPSI command to be sent
- *
- * Returns: 0 on success, error on failure
- */
-int ipc_coredump_get_list(struct iosm_devlink *devlink, u16 cmd);
-
-#endif /* _IOSM_IPC_COREDUMP_H_ */
deleted file mode 100644
@@ -1,360 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2020-2021 Intel Corporation.
- */
-
-#include "iosm_ipc_chnl_cfg.h"
-#include "iosm_ipc_coredump.h"
-#include "iosm_ipc_devlink.h"
-#include "iosm_ipc_flash.h"
-
-/* Coredump list */
-static struct iosm_coredump_file_info list[IOSM_NOF_CD_REGION] = {
- {"report.json", REPORT_JSON_SIZE,},
- {"coredump.fcd", COREDUMP_FCD_SIZE,},
- {"cdd.log", CDD_LOG_SIZE,},
- {"eeprom.bin", EEPROM_BIN_SIZE,},
- {"bootcore_trace.bin", BOOTCORE_TRC_BIN_SIZE,},
- {"bootcore_prev_trace.bin", BOOTCORE_PREV_TRC_BIN_SIZE,},
-};
-
-/* Get the param values for the specific param ID's */
-static int ipc_devlink_get_param(struct devlink *dl, u32 id,
- struct devlink_param_gset_ctx *ctx)
-{
- struct iosm_devlink *ipc_devlink = devlink_priv(dl);
- int rc = 0;
-
- switch (id) {
- case IOSM_DEVLINK_PARAM_ID_ERASE_FULL_FLASH:
- ctx->val.vu8 = ipc_devlink->param.erase_full_flash;
- break;
-
- case IOSM_DEVLINK_PARAM_ID_DOWNLOAD_REGION:
- ctx->val.vu8 = ipc_devlink->param.download_region;
- break;
-
- case IOSM_DEVLINK_PARAM_ID_ADDRESS:
- ctx->val.vu32 = ipc_devlink->param.address;
- break;
-
- case IOSM_DEVLINK_PARAM_ID_REGION_COUNT:
- ctx->val.vu8 = ipc_devlink->param.region_count;
- break;
-
- default:
- rc = -EOPNOTSUPP;
- break;
- }
-
- return rc;
-}
-
-/* Set the param values for the specific param ID's */
-static int ipc_devlink_set_param(struct devlink *dl, u32 id,
- struct devlink_param_gset_ctx *ctx)
-{
- struct iosm_devlink *ipc_devlink = devlink_priv(dl);
- int rc = 0;
-
- switch (id) {
- case IOSM_DEVLINK_PARAM_ID_ERASE_FULL_FLASH:
- ipc_devlink->param.erase_full_flash = ctx->val.vu8;
- break;
-
- case IOSM_DEVLINK_PARAM_ID_DOWNLOAD_REGION:
- ipc_devlink->param.download_region = ctx->val.vu8;
- break;
-
- case IOSM_DEVLINK_PARAM_ID_ADDRESS:
- ipc_devlink->param.address = ctx->val.vu32;
- break;
-
- case IOSM_DEVLINK_PARAM_ID_REGION_COUNT:
- ipc_devlink->param.region_count = ctx->val.vu8;
- break;
-
- default:
- rc = -EOPNOTSUPP;
- break;
- }
-
- return rc;
-}
-
-/* Devlink param structure array */
-static const struct devlink_param iosm_devlink_params[] = {
- DEVLINK_PARAM_DRIVER(IOSM_DEVLINK_PARAM_ID_ERASE_FULL_FLASH,
- "erase_full_flash", DEVLINK_PARAM_TYPE_BOOL,
- BIT(DEVLINK_PARAM_CMODE_RUNTIME),
- ipc_devlink_get_param, ipc_devlink_set_param,
- NULL),
- DEVLINK_PARAM_DRIVER(IOSM_DEVLINK_PARAM_ID_DOWNLOAD_REGION,
- "download_region", DEVLINK_PARAM_TYPE_BOOL,
- BIT(DEVLINK_PARAM_CMODE_RUNTIME),
- ipc_devlink_get_param, ipc_devlink_set_param,
- NULL),
- DEVLINK_PARAM_DRIVER(IOSM_DEVLINK_PARAM_ID_ADDRESS,
- "address", DEVLINK_PARAM_TYPE_U32,
- BIT(DEVLINK_PARAM_CMODE_RUNTIME),
- ipc_devlink_get_param, ipc_devlink_set_param,
- NULL),
- DEVLINK_PARAM_DRIVER(IOSM_DEVLINK_PARAM_ID_REGION_COUNT,
- "region_count", DEVLINK_PARAM_TYPE_U8,
- BIT(DEVLINK_PARAM_CMODE_RUNTIME),
- ipc_devlink_get_param, ipc_devlink_set_param,
- NULL),
-};
-
-/* Get devlink flash component type */
-static enum iosm_flash_comp_type
-ipc_devlink_get_flash_comp_type(const char comp_str[], u32 len)
-{
- enum iosm_flash_comp_type fls_type;
-
- if (!strncmp("PSI", comp_str, len))
- fls_type = FLASH_COMP_TYPE_PSI;
- else if (!strncmp("EBL", comp_str, len))
- fls_type = FLASH_COMP_TYPE_EBL;
- else if (!strncmp("FLS", comp_str, len))
- fls_type = FLASH_COMP_TYPE_FLS;
- else
- fls_type = FLASH_COMP_TYPE_INVAL;
-
- return fls_type;
-}
-
-/* Function triggered on devlink flash command
- * Flash update function which calls multiple functions based on
- * component type specified in the flash command
- */
-static int ipc_devlink_flash_update(struct devlink *devlink,
- struct devlink_flash_update_params *params,
- struct netlink_ext_ack *extack)
-{
- struct iosm_devlink *ipc_devlink = devlink_priv(devlink);
- enum iosm_flash_comp_type fls_type;
- u32 rc = -EINVAL;
- u8 *mdm_rsp;
-
- mdm_rsp = kzalloc(IOSM_EBL_DW_PACK_SIZE, GFP_KERNEL);
- if (!mdm_rsp)
- return -ENOMEM;
-
- fls_type = ipc_devlink_get_flash_comp_type(params->component,
- strlen(params->component));
-
- switch (fls_type) {
- case FLASH_COMP_TYPE_PSI:
- rc = ipc_flash_boot_psi(ipc_devlink, params->fw);
- break;
- case FLASH_COMP_TYPE_EBL:
- rc = ipc_flash_boot_ebl(ipc_devlink, params->fw);
- if (!rc)
- rc = ipc_flash_boot_set_capabilities(ipc_devlink,
- mdm_rsp);
- if (!rc)
- rc = ipc_flash_read_swid(ipc_devlink, mdm_rsp);
- break;
- case FLASH_COMP_TYPE_FLS:
- rc = ipc_flash_send_fls(ipc_devlink, params->fw, mdm_rsp);
- break;
- default:
- devlink_flash_update_status_notify(devlink, "Invalid component",
- params->component, 0, 0);
- break;
- }
-
- if (!rc)
- devlink_flash_update_status_notify(devlink, "Flashing success",
- params->component, 0, 0);
- else
- devlink_flash_update_status_notify(devlink, "Flashing failed",
- params->component, 0, 0);
-
- kfree(mdm_rsp);
- return rc;
-}
-
-/* Call back function for devlink ops */
-static const struct devlink_ops devlink_flash_ops = {
- .supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT,
- .flash_update = ipc_devlink_flash_update,
-};
-
-/* Send command to modem to collect data */
-int ipc_devlink_send_cmd(struct iosm_devlink *ipc_devlink, u16 cmd, u32 entry)
-{
- struct iosm_rpsi_cmd rpsi_cmd;
-
- rpsi_cmd.param.dword = cpu_to_le32(entry);
- rpsi_cmd.cmd = cpu_to_le16(cmd);
- rpsi_cmd.crc = rpsi_cmd.param.word[0] ^ rpsi_cmd.param.word[1] ^
- rpsi_cmd.cmd;
-
- return ipc_imem_sys_devlink_write(ipc_devlink, (u8 *)&rpsi_cmd,
- sizeof(rpsi_cmd));
-}
-
-static int ipc_devlink_coredump_snapshot(struct devlink *dl,
- const struct devlink_region_ops *ops,
- struct netlink_ext_ack *extack,
- u8 **data)
-{
- struct iosm_devlink *ipc_devlink = devlink_priv(dl);
- struct iosm_coredump_file_info *cd_list = ops->priv;
- u32 region_size;
- int rc;
-
- dev_dbg(ipc_devlink->dev, "Region:%s, ID:%d", ops->name,
- cd_list->entry);
- region_size = cd_list->default_size;
- rc = ipc_coredump_collect(ipc_devlink, data, cd_list->entry,
- region_size);
- if (rc) {
- dev_err(ipc_devlink->dev, "Fail to create snapshot,err %d", rc);
- goto coredump_collect_err;
- }
-
- /* Send coredump end cmd indicating end of coredump collection */
- if (cd_list->entry == (IOSM_NOF_CD_REGION - 1))
- ipc_coredump_get_list(ipc_devlink, rpsi_cmd_coredump_end);
-
- return rc;
-coredump_collect_err:
- ipc_coredump_get_list(ipc_devlink, rpsi_cmd_coredump_end);
- return rc;
-}
-
-/* To create regions for coredump files */
-static int ipc_devlink_create_region(struct iosm_devlink *devlink)
-{
- struct devlink_region_ops *mdm_coredump;
- int rc = 0;
- u8 i;
-
- mdm_coredump = devlink->iosm_devlink_mdm_coredump;
- for (i = 0; i < IOSM_NOF_CD_REGION; i++) {
- mdm_coredump[i].name = list[i].filename;
- mdm_coredump[i].snapshot = ipc_devlink_coredump_snapshot;
- mdm_coredump[i].destructor = vfree;
- devlink->cd_regions[i] =
- devlink_region_create(devlink->devlink_ctx,
- &mdm_coredump[i], MAX_SNAPSHOTS,
- list[i].default_size);
-
- if (IS_ERR(devlink->cd_regions[i])) {
- rc = PTR_ERR(devlink->cd_regions[i]);
- dev_err(devlink->dev, "Devlink region fail,err %d", rc);
- /* Delete previously created regions */
- for ( ; i > 0; i--)
- devlink_region_destroy(devlink->cd_regions[i]);
- goto region_create_fail;
- }
- list[i].entry = i;
- mdm_coredump[i].priv = list + i;
- }
-region_create_fail:
- return rc;
-}
-
-/* To Destroy devlink regions */
-static void ipc_devlink_destroy_region(struct iosm_devlink *ipc_devlink)
-{
- u8 i;
-
- for (i = 0; i < IOSM_NOF_CD_REGION; i++)
- devlink_region_destroy(ipc_devlink->cd_regions[i]);
-}
-
-/* Handle registration to devlink framework */
-struct iosm_devlink *ipc_devlink_init(struct iosm_imem *ipc_imem)
-{
- struct ipc_chnl_cfg chnl_cfg_flash = { 0 };
- struct iosm_devlink *ipc_devlink;
- struct devlink *devlink_ctx;
- int rc;
-
- devlink_ctx = devlink_alloc(&devlink_flash_ops,
- sizeof(struct iosm_devlink),
- ipc_imem->dev);
- if (!devlink_ctx) {
- dev_err(ipc_imem->dev, "devlink_alloc failed");
- goto devlink_alloc_fail;
- }
-
- ipc_devlink = devlink_priv(devlink_ctx);
- ipc_devlink->devlink_ctx = devlink_ctx;
- ipc_devlink->pcie = ipc_imem->pcie;
- ipc_devlink->dev = ipc_imem->dev;
- rc = devlink_register(devlink_ctx);
- if (rc) {
- dev_err(ipc_devlink->dev, "devlink_register failed rc %d", rc);
- goto free_dl;
- }
-
- rc = devlink_params_register(devlink_ctx, iosm_devlink_params,
- ARRAY_SIZE(iosm_devlink_params));
- if (rc) {
- dev_err(ipc_devlink->dev,
- "devlink_params_register failed. rc %d", rc);
- goto param_reg_fail;
- }
-
- devlink_params_publish(devlink_ctx);
- ipc_devlink->cd_file_info = list;
-
- rc = ipc_devlink_create_region(ipc_devlink);
- if (rc) {
- dev_err(ipc_devlink->dev, "Devlink Region create failed, rc %d",
- rc);
- goto region_create_fail;
- }
-
- if (ipc_chnl_cfg_get(&chnl_cfg_flash, IPC_MEM_CTRL_CHL_ID_7) < 0)
- goto chnl_get_fail;
-
- ipc_imem_channel_init(ipc_imem, IPC_CTYPE_CTRL,
- chnl_cfg_flash, IRQ_MOD_OFF);
-
- init_completion(&ipc_devlink->devlink_sio.read_sem);
- skb_queue_head_init(&ipc_devlink->devlink_sio.rx_list);
-
- dev_dbg(ipc_devlink->dev, "iosm devlink register success");
-
- return ipc_devlink;
-
-chnl_get_fail:
- ipc_devlink_destroy_region(ipc_devlink);
-region_create_fail:
- devlink_params_unpublish(devlink_ctx);
- devlink_params_unregister(devlink_ctx, iosm_devlink_params,
- ARRAY_SIZE(iosm_devlink_params));
-param_reg_fail:
- devlink_unregister(devlink_ctx);
-free_dl:
- devlink_free(devlink_ctx);
-devlink_alloc_fail:
- return NULL;
-}
-
-/* Handle unregistration of devlink */
-void ipc_devlink_deinit(struct iosm_devlink *ipc_devlink)
-{
- struct devlink *devlink_ctx = ipc_devlink->devlink_ctx;
-
- ipc_devlink_destroy_region(ipc_devlink);
- devlink_params_unpublish(devlink_ctx);
- devlink_params_unregister(devlink_ctx, iosm_devlink_params,
- ARRAY_SIZE(iosm_devlink_params));
- if (ipc_devlink->devlink_sio.devlink_read_pend) {
- complete(&ipc_devlink->devlink_sio.read_sem);
- complete(&ipc_devlink->devlink_sio.channel->ul_sem);
- }
- if (!ipc_devlink->devlink_sio.devlink_read_pend)
- skb_queue_purge(&ipc_devlink->devlink_sio.rx_list);
-
- ipc_imem_sys_devlink_close(ipc_devlink);
- devlink_unregister(devlink_ctx);
- devlink_free(devlink_ctx);
-}
deleted file mode 100644
@@ -1,207 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only
- *
- * Copyright (C) 2020-2021 Intel Corporation.
- */
-
-#ifndef _IOSM_IPC_DEVLINK_H_
-#define _IOSM_IPC_DEVLINK_H_
-
-#include <net/devlink.h>
-
-#include "iosm_ipc_imem.h"
-#include "iosm_ipc_imem_ops.h"
-#include "iosm_ipc_pcie.h"
-
-/* MAX file name length */
-#define IOSM_MAX_FILENAME_LEN 32
-/* EBL response size */
-#define IOSM_EBL_RSP_SIZE 76
-/* MAX number of regions supported */
-#define IOSM_NOF_CD_REGION 6
-/* MAX number of SNAPSHOTS supported */
-#define MAX_SNAPSHOTS 1
-/* Default Coredump file size */
-#define REPORT_JSON_SIZE 0x800
-#define COREDUMP_FCD_SIZE 0x10E00000
-#define CDD_LOG_SIZE 0x30000
-#define EEPROM_BIN_SIZE 0x10000
-#define BOOTCORE_TRC_BIN_SIZE 0x8000
-#define BOOTCORE_PREV_TRC_BIN_SIZE 0x20000
-
-/**
- * enum iosm_devlink_param_id - Enum type to different devlink params
- * @IOSM_DEVLINK_PARAM_ID_BASE: Devlink param base ID
- * @IOSM_DEVLINK_PARAM_ID_ERASE_FULL_FLASH: Set if full erase required
- * @IOSM_DEVLINK_PARAM_ID_DOWNLOAD_REGION: Set if fls file to be
- * flashed is Loadmap/region file
- * @IOSM_DEVLINK_PARAM_ID_ADDRESS: Address of the region to be
- * flashed
- * @IOSM_DEVLINK_PARAM_ID_REGION_COUNT: Max region count
- */
-
-enum iosm_devlink_param_id {
- IOSM_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
- IOSM_DEVLINK_PARAM_ID_ERASE_FULL_FLASH,
- IOSM_DEVLINK_PARAM_ID_DOWNLOAD_REGION,
- IOSM_DEVLINK_PARAM_ID_ADDRESS,
- IOSM_DEVLINK_PARAM_ID_REGION_COUNT,
-};
-
-/**
- * enum iosm_rpsi_cmd_code - Enum type for RPSI command list
- * @rpsi_cmd_code_ebl: Command to load ebl
- * @rpsi_cmd_coredump_start: Command to get list of files and
- * file size info from PSI
- * @rpsi_cmd_coredump_get: Command to get the coredump data
- * @rpsi_cmd_coredump_end: Command to stop receiving the coredump
- */
-enum iosm_rpsi_cmd_code {
- rpsi_cmd_code_ebl = 0x02,
- rpsi_cmd_coredump_start = 0x10,
- rpsi_cmd_coredump_get = 0x11,
- rpsi_cmd_coredump_end = 0x12,
-};
-
-/**
- * enum iosm_flash_comp_type - Enum for different flash component types
- * @FLASH_COMP_TYPE_PSI: PSI flash comp type
- * @FLASH_COMP_TYPE_EBL: EBL flash comp type
- * @FLASH_COMP_TYPE_FLS: FLS flash comp type
- * @FLASH_COMP_TYPE_INVAL: Invalid flash comp type
- */
-enum iosm_flash_comp_type {
- FLASH_COMP_TYPE_PSI,
- FLASH_COMP_TYPE_EBL,
- FLASH_COMP_TYPE_FLS,
- FLASH_COMP_TYPE_INVAL,
-};
-
-/**
- * struct iosm_devlink_sio - SIO instance
- * @rx_list: Downlink skbuf list received from CP
- * @read_sem: Needed for the blocking read or downlink transfer
- * @channel_id: Reserved channel id for flashing/CD collection to RAM
- * @channel: Channel instance for flashing and coredump
- * @devlink_read_pend: Check if read is pending
- */
-struct iosm_devlink_sio {
- struct sk_buff_head rx_list;
- struct completion read_sem;
- int channel_id;
- struct ipc_mem_channel *channel;
- u32 devlink_read_pend;
-};
-
-/**
- * struct iosm_flash_params - List of flash params required for flashing
- * @address: Address of the region file to be flashed
- * @region_count: Maximum no of regions for each fls file
- * @download_region: To be set if region is being flashed
- * @erase_full_flash: To set the flashing mode
- * erase_full_flash = 1; full erase
- * erase_full_flash = 0; no erase
- * @erase_full_flash_done: Flag to check if it is a full erase
- */
-struct iosm_flash_params {
- u32 address;
- u8 region_count;
- u8 download_region;
- u8 erase_full_flash;
- u8 erase_full_flash_done;
-};
-
-/**
- * struct iosm_ebl_ctx_data - EBL ctx data used during flashing
- * @ebl_sw_info_version: SWID version info obtained from EBL
- * @m_ebl_resp: Buffer used to read and write the ebl data
- */
-struct iosm_ebl_ctx_data {
- u8 ebl_sw_info_version;
- u8 m_ebl_resp[IOSM_EBL_RSP_SIZE];
-};
-
-/**
- * struct iosm_coredump_file_info - Coredump file info
- * @filename: Name of coredump file
- * @default_size: Default size of coredump file
- * @actual_size: Actual size of coredump file
- * @entry: Index of the coredump file
- */
-struct iosm_coredump_file_info {
- char filename[IOSM_MAX_FILENAME_LEN];
- u32 default_size;
- u32 actual_size;
- u32 entry;
-};
-
-/**
- * struct iosm_devlink - IOSM Devlink structure
- * @devlink_sio: SIO instance for read/write functionality
- * @pcie: Pointer to PCIe component
- * @dev: Pointer to device struct
- * @devlink_ctx: Pointer to devlink context
- * @param: Params required for flashing
- * @ebl_ctx: Data to be read and written to Modem
- * @cd_file_info: coredump file info
- * @iosm_devlink_mdm_coredump: region ops for coredump collection
- * @cd_regions: coredump regions
- */
-struct iosm_devlink {
- struct iosm_devlink_sio devlink_sio;
- struct iosm_pcie *pcie;
- struct device *dev;
- struct devlink *devlink_ctx;
- struct iosm_flash_params param;
- struct iosm_ebl_ctx_data ebl_ctx;
- struct iosm_coredump_file_info *cd_file_info;
- struct devlink_region_ops iosm_devlink_mdm_coredump[IOSM_NOF_CD_REGION];
- struct devlink_region *cd_regions[IOSM_NOF_CD_REGION];
-};
-
-/**
- * union iosm_rpsi_param_u - RPSI cmd param for CRC calculation
- * @word: Words member used in CRC calculation
- * @dword: Actual data
- */
-union iosm_rpsi_param_u {
- __le16 word[2];
- __le32 dword;
-};
-
-/**
- * struct iosm_rpsi_cmd - Structure for RPSI Command
- * @param: Used to calculate CRC
- * @cmd: Stores the RPSI command
- * @crc: Stores the CRC value
- */
-struct iosm_rpsi_cmd {
- union iosm_rpsi_param_u param;
- __le16 cmd;
- __le16 crc;
-};
-
-/**
- * ipc_devlink_init - To initialize the devlink to IOSM driver
- * @ipc_imem: Pointer to struct iosm_imem
- *
- * Returns: Pointer to iosm_devlink on success and NULL on failure
- */
-struct iosm_devlink *ipc_devlink_init(struct iosm_imem *ipc_imem);
-
-/**
- * ipc_devlink_deinit - To unintialize the devlink from IOSM driver.
- * @ipc_devlink: Devlink instance
- */
-void ipc_devlink_deinit(struct iosm_devlink *ipc_devlink);
-
-/**
- * ipc_devlink_send_cmd - Send command to Modem
- * @ipc_devlink: Pointer to struct iosm_devlink
- * @cmd: Command to be sent to modem
- * @entry: Command entry number
- *
- * Returns: 0 on success and failure value on error
- */
-int ipc_devlink_send_cmd(struct iosm_devlink *ipc_devlink, u16 cmd, u32 entry);
-
-#endif /* _IOSM_IPC_DEVLINK_H */
deleted file mode 100644
@@ -1,562 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2020-2021 Intel Corporation.
- */
-
-#include "iosm_ipc_coredump.h"
-#include "iosm_ipc_devlink.h"
-#include "iosm_ipc_flash.h"
-
-/* This function will pack the data to be sent to the modem using the
- * payload, payload length and pack id
- */
-static int ipc_flash_proc_format_ebl_pack(struct iosm_flash_data *flash_req,
- u32 pack_length, u16 pack_id,
- u8 *payload, u32 payload_length)
-{
- u16 checksum = pack_id;
- u32 i;
-
- if (payload_length + IOSM_EBL_HEAD_SIZE > pack_length)
- return -EINVAL;
-
- flash_req->pack_id = cpu_to_le16(pack_id);
- flash_req->msg_length = cpu_to_le32(payload_length);
- checksum += (payload_length >> IOSM_EBL_PAYL_SHIFT) +
- (payload_length & IOSM_EBL_CKSM);
-
- for (i = 0; i < payload_length; i++)
- checksum += payload[i];
-
- flash_req->checksum = cpu_to_le16(checksum);
-
- return 0;
-}
-
-/* validate the response received from modem and
- * check the type of errors received
- */
-static int ipc_flash_proc_check_ebl_rsp(void *hdr_rsp, void *payload_rsp)
-{
- struct iosm_ebl_error *err_info = payload_rsp;
- u16 *rsp_code = hdr_rsp;
- int res = 0;
- u32 i;
-
- if (*rsp_code == IOSM_EBL_RSP_BUFF) {
- for (i = 0; i < IOSM_MAX_ERRORS; i++) {
- if (!err_info->error[i].error_code) {
- pr_err("EBL: error_class = %d, error_code = %d",
- err_info->error[i].error_class,
- err_info->error[i].error_code);
- }
- }
- res = -EINVAL;
- }
-
- return res;
-}
-
-/* Send data to the modem */
-static int ipc_flash_send_data(struct iosm_devlink *ipc_devlink, u32 size,
- u16 pack_id, u8 *payload, u32 payload_length)
-{
- struct iosm_flash_data flash_req;
- int ret;
-
- ret = ipc_flash_proc_format_ebl_pack(&flash_req, size,
- pack_id, payload, payload_length);
- if (ret) {
- dev_err(ipc_devlink->dev, "EBL2 pack failed for pack_id:%d",
- pack_id);
- goto ipc_free_payload;
- }
-
- ret = ipc_imem_sys_devlink_write(ipc_devlink, (u8 *)&flash_req,
- IOSM_EBL_HEAD_SIZE);
- if (ret) {
- dev_err(ipc_devlink->dev, "EBL Header write failed for Id:%x",
- pack_id);
- goto ipc_free_payload;
- }
-
- ret = ipc_imem_sys_devlink_write(ipc_devlink, payload, payload_length);
- if (ret) {
- dev_err(ipc_devlink->dev, "EBL Payload write failed for Id:%x",
- pack_id);
- }
-
-ipc_free_payload:
- return ret;
-}
-
-/* Allocate flash channel and read LER data from modem */
-int ipc_flash_link_establish(struct iosm_imem *ipc_imem)
-{
- u8 ler_data[IOSM_LER_RSP_SIZE];
- u32 bytes_read;
-
- /* Allocate channel for flashing/cd collection */
- ipc_imem->ipc_devlink->devlink_sio.channel =
- ipc_imem_sys_devlink_open(ipc_imem);
-
- if (!ipc_imem->ipc_devlink->devlink_sio.channel)
- goto chl_open_fail;
-
- if (ipc_imem_sys_devlink_read(ipc_imem->ipc_devlink, ler_data,
- IOSM_LER_RSP_SIZE, &bytes_read))
- goto devlink_read_fail;
-
- if (bytes_read != IOSM_LER_RSP_SIZE)
- goto devlink_read_fail;
- return 0;
-
-devlink_read_fail:
- ipc_imem_sys_devlink_close(ipc_imem->ipc_devlink);
-chl_open_fail:
- return -EIO;
-}
-
-/* Receive data from the modem */
-static int ipc_flash_receive_data(struct iosm_devlink *ipc_devlink, u32 size,
- u8 *mdm_rsp)
-{
- u8 mdm_rsp_hdr[IOSM_EBL_HEAD_SIZE];
- u32 bytes_read;
- int ret;
-
- ret = ipc_imem_sys_devlink_read(ipc_devlink, mdm_rsp_hdr,
- IOSM_EBL_HEAD_SIZE, &bytes_read);
- if (ret) {
- dev_err(ipc_devlink->dev, "EBL rsp to read %d bytes failed",
- IOSM_EBL_HEAD_SIZE);
- goto ipc_flash_recv_err;
- }
-
- if (bytes_read != IOSM_EBL_HEAD_SIZE) {
- ret = -EINVAL;
- goto ipc_flash_recv_err;
- }
-
- ret = ipc_imem_sys_devlink_read(ipc_devlink, mdm_rsp, size,
- &bytes_read);
- if (ret) {
- dev_err(ipc_devlink->dev, "EBL rsp to read %d bytes failed",
- size);
- goto ipc_flash_recv_err;
- }
-
- if (bytes_read != size) {
- ret = -EINVAL;
- goto ipc_flash_recv_err;
- }
-
- ret = ipc_flash_proc_check_ebl_rsp(mdm_rsp_hdr + 2, mdm_rsp);
-
-ipc_flash_recv_err:
- return ret;
-}
-
-/* Function to send command to modem and receive response */
-static int ipc_flash_send_receive(struct iosm_devlink *ipc_devlink, u16 pack_id,
- u8 *payload, u32 payload_length, u8 *mdm_rsp)
-{
- size_t frame_len = IOSM_EBL_DW_PACK_SIZE;
- int ret;
-
- if (pack_id == FLASH_SET_PROT_CONF)
- frame_len = IOSM_EBL_W_PACK_SIZE;
-
- ret = ipc_flash_send_data(ipc_devlink, frame_len, pack_id, payload,
- payload_length);
- if (ret)
- goto ipc_flash_send_rcv;
-
- ret = ipc_flash_receive_data(ipc_devlink,
- frame_len - IOSM_EBL_HEAD_SIZE, mdm_rsp);
-
-ipc_flash_send_rcv:
- return ret;
-}
-
-/* Set the capabilities for the EBL */
-int ipc_flash_boot_set_capabilities(struct iosm_devlink *ipc_devlink,
- u8 *mdm_rsp)
-{
- int ret;
-
- ipc_devlink->ebl_ctx.ebl_sw_info_version =
- ipc_devlink->ebl_ctx.m_ebl_resp[EBL_RSP_SW_INFO_VER];
- ipc_devlink->ebl_ctx.m_ebl_resp[EBL_SKIP_ERASE] = IOSM_CAP_NOT_ENHANCED;
- ipc_devlink->ebl_ctx.m_ebl_resp[EBL_SKIP_CRC] = IOSM_CAP_NOT_ENHANCED;
-
- if (ipc_devlink->ebl_ctx.m_ebl_resp[EBL_CAPS_FLAG] &
- IOSM_CAP_USE_EXT_CAP) {
- if (ipc_devlink->param.erase_full_flash)
- ipc_devlink->ebl_ctx.m_ebl_resp[EBL_OOS_CONFIG] &=
- ~((u8)IOSM_EXT_CAP_ERASE_ALL);
- else
- ipc_devlink->ebl_ctx.m_ebl_resp[EBL_OOS_CONFIG] &=
- ~((u8)IOSM_EXT_CAP_COMMIT_ALL);
- ipc_devlink->ebl_ctx.m_ebl_resp[EBL_EXT_CAPS_HANDLED] =
- IOSM_CAP_USE_EXT_CAP;
- }
-
- /* Write back the EBL capability to modem
- * Request Set Protcnf command
- */
- ret = ipc_flash_send_receive(ipc_devlink, FLASH_SET_PROT_CONF,
- ipc_devlink->ebl_ctx.m_ebl_resp,
- IOSM_EBL_RSP_SIZE, mdm_rsp);
- return ret;
-}
-
-/* Read the SWID type and SWID value from the EBL */
-int ipc_flash_read_swid(struct iosm_devlink *ipc_devlink, u8 *mdm_rsp)
-{
- struct iosm_flash_msg_control cmd_msg;
- struct iosm_swid_table *swid;
- char ebl_swid[IOSM_SWID_STR];
- int ret;
-
- if (ipc_devlink->ebl_ctx.ebl_sw_info_version !=
- IOSM_EXT_CAP_SWID_OOS_PACK)
- return -EINVAL;
-
- cmd_msg.action = cpu_to_le32(FLASH_OOSC_ACTION_READ);
- cmd_msg.type = cpu_to_le32(FLASH_OOSC_TYPE_SWID_TABLE);
- cmd_msg.length = cpu_to_le32(IOSM_MSG_LEN_ARG);
- cmd_msg.arguments = cpu_to_le32(IOSM_MSG_LEN_ARG);
-
- ret = ipc_flash_send_receive(ipc_devlink, FLASH_OOS_CONTROL,
- (u8 *)&cmd_msg, IOSM_MDM_SEND_16, mdm_rsp);
- if (ret)
- goto ipc_swid_err;
-
- cmd_msg.action = cpu_to_le32(*((u32 *)mdm_rsp));
-
- ret = ipc_flash_send_receive(ipc_devlink, FLASH_OOS_DATA_READ,
- (u8 *)&cmd_msg, IOSM_MDM_SEND_4, mdm_rsp);
- if (ret)
- goto ipc_swid_err;
-
- swid = (struct iosm_swid_table *)mdm_rsp;
- dev_dbg(ipc_devlink->dev, "SWID %x RF_ENGINE_ID %x", swid->sw_id_val,
- swid->rf_engine_id_val);
-
- snprintf(ebl_swid, sizeof(ebl_swid), "SWID: %x, RF_ENGINE_ID: %x",
- swid->sw_id_val, swid->rf_engine_id_val);
-
- devlink_flash_update_status_notify(ipc_devlink->devlink_ctx, ebl_swid,
- NULL, 0, 0);
-ipc_swid_err:
- return ret;
-}
-
-/* Function to check if full erase or conditional erase was successful */
-static int ipc_flash_erase_check(struct iosm_devlink *ipc_devlink, u8 *mdm_rsp)
-{
- int ret, count = 0;
- u16 mdm_rsp_data;
-
- /* Request Flash Erase Check */
- do {
- mdm_rsp_data = IOSM_MDM_SEND_DATA;
- ret = ipc_flash_send_receive(ipc_devlink, FLASH_ERASE_CHECK,
- (u8 *)&mdm_rsp_data,
- IOSM_MDM_SEND_2, mdm_rsp);
- if (ret)
- goto ipc_erase_chk_err;
-
- mdm_rsp_data = *((u16 *)mdm_rsp);
- if (mdm_rsp_data > IOSM_MDM_ERASE_RSP) {
- dev_err(ipc_devlink->dev,
- "Flash Erase Check resp wrong 0x%04X",
- mdm_rsp_data);
- ret = -EINVAL;
- goto ipc_erase_chk_err;
- }
- count++;
- msleep(IOSM_FLASH_ERASE_CHECK_INTERVAL);
- } while ((mdm_rsp_data != IOSM_MDM_ERASE_RSP) &&
- (count < (IOSM_FLASH_ERASE_CHECK_TIMEOUT /
- IOSM_FLASH_ERASE_CHECK_INTERVAL)));
-
- if (mdm_rsp_data != IOSM_MDM_ERASE_RSP) {
- dev_err(ipc_devlink->dev, "Modem erase check timeout failure!");
- ret = -ETIMEDOUT;
- }
-
-ipc_erase_chk_err:
- return ret;
-}
-
-/* Full erase function which will erase the nand flash through EBL command */
-static int ipc_flash_full_erase(struct iosm_devlink *ipc_devlink, u8 *mdm_rsp)
-{
- u32 erase_address = IOSM_ERASE_START_ADDR;
- struct iosm_flash_msg_control cmd_msg;
- u32 erase_length = IOSM_ERASE_LEN;
- int ret;
-
- dev_dbg(ipc_devlink->dev, "Erase full nand flash");
- cmd_msg.action = cpu_to_le32(FLASH_OOSC_ACTION_ERASE);
- cmd_msg.type = cpu_to_le32(FLASH_OOSC_TYPE_ALL_FLASH);
- cmd_msg.length = cpu_to_le32(erase_length);
- cmd_msg.arguments = cpu_to_le32(erase_address);
-
- ret = ipc_flash_send_receive(ipc_devlink, FLASH_OOS_CONTROL,
- (unsigned char *)&cmd_msg,
- IOSM_MDM_SEND_16, mdm_rsp);
- if (ret)
- goto ipc_flash_erase_err;
-
- ipc_devlink->param.erase_full_flash_done = IOSM_SET_FLAG;
- ret = ipc_flash_erase_check(ipc_devlink, mdm_rsp);
-
-ipc_flash_erase_err:
- return ret;
-}
-
-/* Logic for flashing all the Loadmaps available for individual fls file */
-static int ipc_flash_download_region(struct iosm_devlink *ipc_devlink,
- const struct firmware *fw, u8 *mdm_rsp)
-{
- __le32 reg_info[2]; /* 0th position region address, 1st position size */
- char *file_ptr;
- u32 rest_len;
- u32 raw_len;
- int ret;
-
- file_ptr = (char *)fw->data;
- reg_info[0] = cpu_to_le32(ipc_devlink->param.address);
-
- if (!ipc_devlink->param.erase_full_flash_done) {
- reg_info[1] = cpu_to_le32(ipc_devlink->param.address +
- fw->size - 2);
- ret = ipc_flash_send_receive(ipc_devlink, FLASH_ERASE_START,
- (u8 *)reg_info, IOSM_MDM_SEND_8,
- mdm_rsp);
- if (ret)
- goto dl_region_fail;
-
- ret = ipc_flash_erase_check(ipc_devlink, mdm_rsp);
- if (ret)
- goto dl_region_fail;
- }
-
- /* Request Flash Set Address */
- ret = ipc_flash_send_receive(ipc_devlink, FLASH_SET_ADDRESS,
- (u8 *)reg_info, IOSM_MDM_SEND_4, mdm_rsp);
- if (ret)
- goto dl_region_fail;
-
- rest_len = fw->size;
-
- /* Request Flash Write Raw Image */
- ret = ipc_flash_send_data(ipc_devlink, IOSM_EBL_DW_PACK_SIZE,
- FLASH_WRITE_IMAGE_RAW, (u8 *)&rest_len,
- IOSM_MDM_SEND_4);
- if (ret)
- goto dl_region_fail;
-
- do {
- raw_len = (rest_len > IOSM_FLS_BUF_SIZE) ? IOSM_FLS_BUF_SIZE :
- rest_len;
- ret = ipc_imem_sys_devlink_write(ipc_devlink, file_ptr,
- raw_len);
- if (ret) {
- dev_err(ipc_devlink->dev, "Image write failed");
- goto dl_region_fail;
- }
- file_ptr += raw_len;
- rest_len -= raw_len;
- } while (rest_len);
-
- ret = ipc_flash_receive_data(ipc_devlink, IOSM_EBL_DW_PAYL_SIZE,
- mdm_rsp);
-
-dl_region_fail:
- return ret;
-}
-
-/* Flash the individual fls files */
-int ipc_flash_send_fls(struct iosm_devlink *ipc_devlink,
- const struct firmware *fw, u8 *mdm_rsp)
-{
- u16 flash_cmd;
- int ret;
-
- if (ipc_devlink->param.erase_full_flash) {
- ipc_devlink->param.erase_full_flash = false;
- ret = ipc_flash_full_erase(ipc_devlink, mdm_rsp);
- if (ret)
- goto ipc_flash_err;
- }
-
- /* Request Sec Start */
- if (!ipc_devlink->param.download_region) {
- ret = ipc_flash_send_receive(ipc_devlink, FLASH_SEC_START,
- (u8 *)fw->data, fw->size, mdm_rsp);
- if (ret)
- goto ipc_flash_err;
- } else {
- /* Download regions */
- ipc_devlink->param.region_count -= IOSM_SET_FLAG;
- ret = ipc_flash_download_region(ipc_devlink, fw, mdm_rsp);
- if (ret)
- goto ipc_flash_err;
-
- if (!ipc_devlink->param.region_count) {
- /* Request Sec End */
- flash_cmd = IOSM_MDM_SEND_DATA;
- ret = ipc_flash_send_receive(ipc_devlink, FLASH_SEC_END,
- (u8 *)&flash_cmd,
- IOSM_MDM_SEND_2, mdm_rsp);
- }
- }
-
-ipc_flash_err:
- return ret;
-}
-
-/* Inject RPSI */
-int ipc_flash_boot_psi(struct iosm_devlink *ipc_devlink,
- const struct firmware *fw)
-{
- u8 psi_ack_byte[IOSM_PSI_ACK], read_data[2];
- u32 bytes_read;
- u8 *psi_code;
- int ret;
-
- dev_dbg(ipc_devlink->dev, "Boot transfer PSI");
- psi_code = kzalloc(fw->size, GFP_KERNEL);
- if (!psi_code)
- return -ENOMEM;
-
- memcpy(psi_code, fw->data, fw->size);
- ret = ipc_imem_sys_devlink_write(ipc_devlink, psi_code, fw->size);
- if (ret) {
- dev_err(ipc_devlink->dev, "RPSI Image write failed");
- goto ipc_flash_psi_free;
- }
-
- ret = ipc_imem_sys_devlink_read(ipc_devlink, read_data,
- IOSM_LER_ACK_SIZE, &bytes_read);
- if (ret) {
- dev_err(ipc_devlink->dev, "ipc_devlink_sio_read ACK failed");
- goto ipc_flash_psi_free;
- }
-
- if (bytes_read != IOSM_LER_ACK_SIZE) {
- ret = -EINVAL;
- goto ipc_flash_psi_free;
- }
-
- snprintf(psi_ack_byte, sizeof(psi_ack_byte), "%x%x", read_data[0],
- read_data[1]);
- devlink_flash_update_status_notify(ipc_devlink->devlink_ctx,
- psi_ack_byte, "PSI ACK", 0, 0);
-
- if (read_data[0] == 0x00 && read_data[1] == 0xCD) {
- dev_dbg(ipc_devlink->dev, "Coredump detected");
- ret = ipc_coredump_get_list(ipc_devlink,
- rpsi_cmd_coredump_start);
- if (ret)
- dev_err(ipc_devlink->dev, "Failed to get cd list");
- }
-
-ipc_flash_psi_free:
- kfree(psi_code);
- return ret;
-}
-
-/* Inject EBL */
-int ipc_flash_boot_ebl(struct iosm_devlink *ipc_devlink,
- const struct firmware *fw)
-{
- u32 ebl_size = fw->size;
- u8 read_data[2];
- u32 bytes_read;
- int ret;
-
- if (ipc_mmio_get_exec_stage(ipc_devlink->pcie->imem->mmio) !=
- IPC_MEM_EXEC_STAGE_PSI) {
- devlink_flash_update_status_notify(ipc_devlink->devlink_ctx,
- "Invalid execution stage",
- NULL, 0, 0);
- return -EINVAL;
- }
-
- dev_dbg(ipc_devlink->dev, "Boot transfer EBL");
- ret = ipc_devlink_send_cmd(ipc_devlink, rpsi_cmd_code_ebl,
- IOSM_RPSI_LOAD_SIZE);
- if (ret) {
- dev_err(ipc_devlink->dev, "Sending rpsi_cmd_code_ebl failed");
- goto ipc_flash_ebl_err;
- }
-
- ret = ipc_imem_sys_devlink_read(ipc_devlink, read_data, IOSM_READ_SIZE,
- &bytes_read);
- if (ret) {
- dev_err(ipc_devlink->dev, "rpsi_cmd_code_ebl read failed");
- goto ipc_flash_ebl_err;
- }
-
- if (bytes_read != IOSM_READ_SIZE) {
- ret = -EINVAL;
- goto ipc_flash_ebl_err;
- }
-
- ret = ipc_imem_sys_devlink_write(ipc_devlink, (u8 *)&ebl_size,
- sizeof(ebl_size));
- if (ret) {
- dev_err(ipc_devlink->dev, "EBL length write failed");
- goto ipc_flash_ebl_err;
- }
-
- ret = ipc_imem_sys_devlink_read(ipc_devlink, read_data, IOSM_READ_SIZE,
- &bytes_read);
- if (ret) {
- dev_err(ipc_devlink->dev, "EBL read failed");
- goto ipc_flash_ebl_err;
- }
-
- if (bytes_read != IOSM_READ_SIZE) {
- ret = -EINVAL;
- goto ipc_flash_ebl_err;
- }
-
- ret = ipc_imem_sys_devlink_write(ipc_devlink, (unsigned char *)fw->data,
- fw->size);
- if (ret) {
- dev_err(ipc_devlink->dev, "EBL data transfer failed");
- goto ipc_flash_ebl_err;
- }
-
- ret = ipc_imem_sys_devlink_read(ipc_devlink, read_data, IOSM_READ_SIZE,
- &bytes_read);
- if (ret) {
- dev_err(ipc_devlink->dev, "EBL read failed");
- goto ipc_flash_ebl_err;
- }
-
- if (bytes_read != IOSM_READ_SIZE) {
- ret = -EINVAL;
- goto ipc_flash_ebl_err;
- }
-
- ret = ipc_imem_sys_devlink_read(ipc_devlink,
- ipc_devlink->ebl_ctx.m_ebl_resp,
- IOSM_EBL_RSP_SIZE, &bytes_read);
- if (ret) {
- dev_err(ipc_devlink->dev, "EBL response read failed");
- goto ipc_flash_ebl_err;
- }
-
- if (bytes_read != IOSM_EBL_RSP_SIZE)
- ret = -EINVAL;
-
-ipc_flash_ebl_err:
- return ret;
-}
deleted file mode 100644
@@ -1,271 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only
- *
- * Copyright (C) 2020-2021 Intel Corporation.
- */
-
-#ifndef _IOSM_IPC_FLASH_H
-#define _IOSM_IPC_FLASH_H
-
-/* Buffer size used to read the fls image */
-#define IOSM_FLS_BUF_SIZE 0x00100000
-/* Full erase start address */
-#define IOSM_ERASE_START_ADDR 0x00000000
-/* Erase length for NAND flash */
-#define IOSM_ERASE_LEN 0xFFFFFFFF
-/* EBL response Header size */
-#define IOSM_EBL_HEAD_SIZE 8
-/* EBL payload size */
-#define IOSM_EBL_W_PAYL_SIZE 2048
-/* Total EBL pack size */
-#define IOSM_EBL_W_PACK_SIZE (IOSM_EBL_HEAD_SIZE + IOSM_EBL_W_PAYL_SIZE)
-/* EBL payload size */
-#define IOSM_EBL_DW_PAYL_SIZE 16384
-/* Total EBL pack size */
-#define IOSM_EBL_DW_PACK_SIZE (IOSM_EBL_HEAD_SIZE + IOSM_EBL_DW_PAYL_SIZE)
-/* EBL name size */
-#define IOSM_EBL_NAME 32
-/* Maximum supported error types */
-#define IOSM_MAX_ERRORS 8
-/* Read size for RPSI/EBL response */
-#define IOSM_READ_SIZE 2
-/* Link establishment response ack size */
-#define IOSM_LER_ACK_SIZE 2
-/* PSI ACK len */
-#define IOSM_PSI_ACK 8
-/* SWID capability for packed swid type */
-#define IOSM_EXT_CAP_SWID_OOS_PACK 0x02
-/* EBL error response buffer */
-#define IOSM_EBL_RSP_BUFF 0x0041
-/* SWID string length */
-#define IOSM_SWID_STR 64
-/* Load EBL command size */
-#define IOSM_RPSI_LOAD_SIZE 0
-/* EBL payload checksum */
-#define IOSM_EBL_CKSM 0x0000FFFF
-/* SWID msg len and argument */
-#define IOSM_MSG_LEN_ARG 0
-/* Data to be sent to modem */
-#define IOSM_MDM_SEND_DATA 0x0000
-/* Data received from modem as part of erase check */
-#define IOSM_MDM_ERASE_RSP 0x0001
-/* Bit shift to calculate Checksum */
-#define IOSM_EBL_PAYL_SHIFT 16
-/* Flag To be set */
-#define IOSM_SET_FLAG 1
-/* Set flash erase check timeout to 100 msec */
-#define IOSM_FLASH_ERASE_CHECK_TIMEOUT 100
-/* Set flash erase check interval to 20 msec */
-#define IOSM_FLASH_ERASE_CHECK_INTERVAL 20
-/* Link establishment response ack size */
-#define IOSM_LER_RSP_SIZE 60
-
-/**
- * enum iosm_flash_package_type - Enum for the flashing operations
- * @FLASH_SET_PROT_CONF: Write EBL capabilities
- * @FLASH_SEC_START: Start writing the secpack
- * @FLASH_SEC_END: Validate secpack end
- * @FLASH_SET_ADDRESS: Set the address for flashing
- * @FLASH_ERASE_START: Start erase before flashing
- * @FLASH_ERASE_CHECK: Validate the erase functionality
- * @FLASH_OOS_CONTROL: Retrieve data based on oos actions
- * @FLASH_OOS_DATA_READ: Read data from EBL
- * @FLASH_WRITE_IMAGE_RAW: Write the raw image to flash
- */
-enum iosm_flash_package_type {
- FLASH_SET_PROT_CONF = 0x0086,
- FLASH_SEC_START = 0x0204,
- FLASH_SEC_END,
- FLASH_SET_ADDRESS = 0x0802,
- FLASH_ERASE_START = 0x0805,
- FLASH_ERASE_CHECK,
- FLASH_OOS_CONTROL = 0x080C,
- FLASH_OOS_DATA_READ = 0x080E,
- FLASH_WRITE_IMAGE_RAW,
-};
-
-/**
- * enum iosm_out_of_session_action - Actions possible over the
- * OutOfSession command interface
- * @FLASH_OOSC_ACTION_READ: Read data according to its type
- * @FLASH_OOSC_ACTION_ERASE: Erase data according to its type
- */
-enum iosm_out_of_session_action {
- FLASH_OOSC_ACTION_READ = 2,
- FLASH_OOSC_ACTION_ERASE = 3,
-};
-
-/**
- * enum iosm_out_of_session_type - Data types that can be handled over the
- * Out Of Session command Interface
- * @FLASH_OOSC_TYPE_ALL_FLASH: The whole flash area
- * @FLASH_OOSC_TYPE_SWID_TABLE: Read the swid table from the target
- */
-enum iosm_out_of_session_type {
- FLASH_OOSC_TYPE_ALL_FLASH = 8,
- FLASH_OOSC_TYPE_SWID_TABLE = 16,
-};
-
-/**
- * enum iosm_ebl_caps - EBL capability settings
- * @IOSM_CAP_NOT_ENHANCED: If capability not supported
- * @IOSM_CAP_USE_EXT_CAP: To be set if extended capability is set
- * @IOSM_EXT_CAP_ERASE_ALL: Set Erase all capability
- * @IOSM_EXT_CAP_COMMIT_ALL: Set the commit all capability
- */
-enum iosm_ebl_caps {
- IOSM_CAP_NOT_ENHANCED = 0x00,
- IOSM_CAP_USE_EXT_CAP = 0x01,
- IOSM_EXT_CAP_ERASE_ALL = 0x08,
- IOSM_EXT_CAP_COMMIT_ALL = 0x20,
-};
-
-/**
- * enum iosm_ebl_rsp - EBL response field
- * @EBL_CAPS_FLAG: EBL capability flag
- * @EBL_SKIP_ERASE: EBL skip erase flag
- * @EBL_SKIP_CRC: EBL skip wr_pack crc
- * @EBL_EXT_CAPS_HANDLED: EBL extended capability handled flag
- * @EBL_OOS_CONFIG: EBL oos configuration
- * @EBL_RSP_SW_INFO_VER: EBL SW info version
- */
-enum iosm_ebl_rsp {
- EBL_CAPS_FLAG = 50,
- EBL_SKIP_ERASE = 54,
- EBL_SKIP_CRC = 55,
- EBL_EXT_CAPS_HANDLED = 57,
- EBL_OOS_CONFIG = 64,
- EBL_RSP_SW_INFO_VER = 70,
-};
-
-/**
- * enum iosm_mdm_send_recv_data - Data to send to modem
- * @IOSM_MDM_SEND_2: Send 2 bytes of payload
- * @IOSM_MDM_SEND_4: Send 4 bytes of payload
- * @IOSM_MDM_SEND_8: Send 8 bytes of payload
- * @IOSM_MDM_SEND_16: Send 16 bytes of payload
- */
-enum iosm_mdm_send_recv_data {
- IOSM_MDM_SEND_2 = 2,
- IOSM_MDM_SEND_4 = 4,
- IOSM_MDM_SEND_8 = 8,
- IOSM_MDM_SEND_16 = 16,
-};
-
-/**
- * struct iosm_ebl_one_error - Structure containing error details
- * @error_class: Error type- standard, security and text error
- * @error_code: Specific error from error type
- */
-struct iosm_ebl_one_error {
- u16 error_class;
- u16 error_code;
-};
-
-/**
- * struct iosm_ebl_error- Structure with max error type supported
- * @error: Array of one_error structure with max errors
- */
-struct iosm_ebl_error {
- struct iosm_ebl_one_error error[IOSM_MAX_ERRORS];
-};
-
-/**
- * struct iosm_swid_table - SWID table data for modem
- * @number_of_data_sets: Number of swid types
- * @sw_id_type: SWID type - SWID
- * @sw_id_val: SWID value
- * @rf_engine_id_type: RF engine ID type - RF_ENGINE_ID
- * @rf_engine_id_val: RF engine ID value
- */
-struct iosm_swid_table {
- u32 number_of_data_sets;
- char sw_id_type[IOSM_EBL_NAME];
- u32 sw_id_val;
- char rf_engine_id_type[IOSM_EBL_NAME];
- u32 rf_engine_id_val;
-};
-
-/**
- * struct iosm_flash_msg_control - Data sent to modem
- * @action: Action to be performed
- * @type: Type of action
- * @length: Length of the action
- * @arguments: Argument value sent to modem
- */
-struct iosm_flash_msg_control {
- __le32 action;
- __le32 type;
- __le32 length;
- __le32 arguments;
-};
-
-/**
- * struct iosm_flash_data - Header Data to be sent to modem
- * @checksum: Checksum value calculated for the payload data
- * @pack_id: Flash Action type
- * @msg_length: Payload length
- */
-struct iosm_flash_data {
- __le16 checksum;
- __le16 pack_id;
- __le32 msg_length;
-};
-
-/**
- * ipc_flash_boot_psi - Inject PSI image
- * @ipc_devlink: Pointer to devlink structure
- * @fw: FW image
- *
- * Returns: 0 on success and failure value on error
- */
-int ipc_flash_boot_psi(struct iosm_devlink *ipc_devlink,
- const struct firmware *fw);
-
-/**
- * ipc_flash_boot_ebl - Inject EBL image
- * @ipc_devlink: Pointer to devlink structure
- * @fw: FW image
- *
- * Returns: 0 on success and failure value on error
- */
-int ipc_flash_boot_ebl(struct iosm_devlink *ipc_devlink,
- const struct firmware *fw);
-
-/**
- * ipc_flash_boot_set_capabilities - Set modem bool capabilities in flash
- * @ipc_devlink: Pointer to devlink structure
- * @mdm_rsp: Pointer to modem response buffer
- *
- * Returns: 0 on success and failure value on error
- */
-int ipc_flash_boot_set_capabilities(struct iosm_devlink *ipc_devlink,
- u8 *mdm_rsp);
-
-/**
- * ipc_flash_link_establish - Flash link establishment
- * @ipc_imem: Pointer to struct iosm_imem
- *
- * Returns: 0 on success and failure value on error
- */
-int ipc_flash_link_establish(struct iosm_imem *ipc_imem);
-
-/**
- * ipc_flash_read_swid - Get swid during flash phase
- * @ipc_devlink: Pointer to devlink structure
- * @mdm_rsp: Pointer to modem response buffer
- *
- * Returns: 0 on success and failure value on error
- */
-int ipc_flash_read_swid(struct iosm_devlink *ipc_devlink, u8 *mdm_rsp);
-
-/**
- * ipc_flash_send_fls - Inject Modem subsystem fls file to device
- * @ipc_devlink: Pointer to devlink structure
- * @fw: FW image
- * @mdm_rsp: Pointer to modem response buffer
- *
- * Returns: 0 on success and failure value on error
- */
-int ipc_flash_send_fls(struct iosm_devlink *ipc_devlink,
- const struct firmware *fw, u8 *mdm_rsp);
-#endif
@@ -6,8 +6,6 @@
#include <linux/delay.h>
#include "iosm_ipc_chnl_cfg.h"
-#include "iosm_ipc_devlink.h"
-#include "iosm_ipc_flash.h"
#include "iosm_ipc_imem.h"
#include "iosm_ipc_port.h"
@@ -265,12 +263,9 @@ static void ipc_imem_dl_skb_process(struct iosm_imem *ipc_imem,
switch (pipe->channel->ctype) {
case IPC_CTYPE_CTRL:
port_id = pipe->channel->channel_id;
- if (port_id == IPC_MEM_CTRL_CHL_ID_7)
- ipc_imem_sys_devlink_notify_rx(ipc_imem->ipc_devlink,
- skb);
- else
- wwan_port_rx(ipc_imem->ipc_port[port_id]->iosm_port,
- skb);
+
+ /* Pass the packet to the wwan layer. */
+ wwan_port_rx(ipc_imem->ipc_port[port_id]->iosm_port, skb);
break;
case IPC_CTYPE_WWAN:
@@ -404,8 +399,19 @@ static void ipc_imem_rom_irq_exec(struct iosm_imem *ipc_imem)
{
struct ipc_mem_channel *channel;
- channel = ipc_imem->ipc_devlink->devlink_sio.channel;
+ if (ipc_imem->flash_channel_id < 0) {
+ ipc_imem->rom_exit_code = IMEM_ROM_EXIT_FAIL;
+ dev_err(ipc_imem->dev, "Missing flash app:%d",
+ ipc_imem->flash_channel_id);
+ return;
+ }
+
ipc_imem->rom_exit_code = ipc_mmio_get_rom_exit_code(ipc_imem->mmio);
+
+ /* Wake up the flash app to continue or to terminate depending
+ * on the CP ROM exit code.
+ */
+ channel = &ipc_imem->channels[ipc_imem->flash_channel_id];
complete(&channel->ul_sem);
}
@@ -566,7 +572,7 @@ static void ipc_imem_handle_irq(struct iosm_imem *ipc_imem, int irq)
enum ipc_phase old_phase, phase;
bool retry_allocation = false;
bool ul_pending = false;
- int i;
+ int ch_id, i;
if (irq != IMEM_IRQ_DONT_CARE)
ipc_imem->ev_irq_pending[irq] = false;
@@ -690,8 +696,11 @@ static void ipc_imem_handle_irq(struct iosm_imem *ipc_imem, int irq)
if ((phase == IPC_P_PSI || phase == IPC_P_EBL) &&
ipc_imem->ipc_requested_state == IPC_MEM_DEVICE_IPC_RUNNING &&
ipc_mmio_get_ipc_state(ipc_imem->mmio) ==
- IPC_MEM_DEVICE_IPC_RUNNING) {
- complete(&ipc_imem->ipc_devlink->devlink_sio.channel->ul_sem);
+ IPC_MEM_DEVICE_IPC_RUNNING &&
+ ipc_imem->flash_channel_id >= 0) {
+ /* Wake up the flash app to open the pipes. */
+ ch_id = ipc_imem->flash_channel_id;
+ complete(&ipc_imem->channels[ch_id].ul_sem);
}
/* Reset the expected CP state. */
@@ -1167,9 +1176,6 @@ void ipc_imem_cleanup(struct iosm_imem *ipc_imem)
ipc_port_deinit(ipc_imem->ipc_port);
}
- if (ipc_imem->ipc_devlink)
- ipc_devlink_deinit(ipc_imem->ipc_devlink);
-
ipc_imem_device_ipc_uninit(ipc_imem);
ipc_imem_channel_reset(ipc_imem);
@@ -1252,7 +1258,6 @@ struct iosm_imem *ipc_imem_init(struct iosm_pcie *pcie, unsigned int device_id,
void __iomem *mmio, struct device *dev)
{
struct iosm_imem *ipc_imem = kzalloc(sizeof(*pcie->imem), GFP_KERNEL);
- enum ipc_mem_exec_stage stage;
if (!ipc_imem)
return NULL;
@@ -1267,6 +1272,9 @@ struct iosm_imem *ipc_imem_init(struct iosm_pcie *pcie, unsigned int device_id,
ipc_imem->cp_version = 0;
ipc_imem->device_sleep = IPC_HOST_SLEEP_ENTER_SLEEP;
+ /* Reset the flash channel id. */
+ ipc_imem->flash_channel_id = -1;
+
/* Reset the max number of configured channels */
ipc_imem->nr_of_channels = 0;
@@ -1320,21 +1328,8 @@ struct iosm_imem *ipc_imem_init(struct iosm_pcie *pcie, unsigned int device_id,
goto imem_config_fail;
}
- stage = ipc_mmio_get_exec_stage(ipc_imem->mmio);
- if (stage == IPC_MEM_EXEC_STAGE_BOOT) {
- /* Alloc and Register devlink */
- ipc_imem->ipc_devlink = ipc_devlink_init(ipc_imem);
- if (!ipc_imem->ipc_devlink) {
- dev_err(ipc_imem->dev, "Devlink register failed");
- goto imem_config_fail;
- }
-
- if (ipc_flash_link_establish(ipc_imem))
- goto devlink_channel_fail;
- }
return ipc_imem;
-devlink_channel_fail:
- ipc_devlink_deinit(ipc_imem->ipc_devlink);
+
imem_config_fail:
hrtimer_cancel(&ipc_imem->td_alloc_timer);
hrtimer_cancel(&ipc_imem->fast_update_timer);
@@ -1366,51 +1361,3 @@ void ipc_imem_td_update_timer_suspend(struct iosm_imem *ipc_imem, bool suspend)
{
ipc_imem->td_update_timer_suspended = suspend;
}
-
-/* Verify the CP execution state, copy the chip info,
- * change the execution phase to ROM
- */
-static int ipc_imem_devlink_trigger_chip_info_cb(struct iosm_imem *ipc_imem,
- int arg, void *msg,
- size_t msgsize)
-{
- enum ipc_mem_exec_stage stage;
- struct sk_buff *skb;
- int rc = -EINVAL;
- size_t size;
-
- /* Test the CP execution state. */
- stage = ipc_mmio_get_exec_stage(ipc_imem->mmio);
- if (stage != IPC_MEM_EXEC_STAGE_BOOT) {
- dev_err(ipc_imem->dev,
- "Execution_stage: expected BOOT, received = %X", stage);
- goto trigger_chip_info_fail;
- }
- /* Allocate a new sk buf for the chip info. */
- size = ipc_imem->mmio->chip_info_size;
- if (size > IOSM_CHIP_INFO_SIZE_MAX)
- goto trigger_chip_info_fail;
-
- skb = ipc_pcie_alloc_local_skb(ipc_imem->pcie, GFP_ATOMIC, size);
- if (!skb) {
- dev_err(ipc_imem->dev, "exhausted skbuf kernel DL memory");
- rc = -ENOMEM;
- goto trigger_chip_info_fail;
- }
- /* Copy the chip info characters into the ipc_skb. */
- ipc_mmio_copy_chip_info(ipc_imem->mmio, skb_put(skb, size), size);
- /* First change to the ROM boot phase. */
- dev_dbg(ipc_imem->dev, "execution_stage[%X] eq. BOOT", stage);
- ipc_imem->phase = ipc_imem_phase_update(ipc_imem);
- ipc_imem_sys_devlink_notify_rx(ipc_imem->ipc_devlink, skb);
- rc = 0;
-trigger_chip_info_fail:
- return rc;
-}
-
-int ipc_imem_devlink_trigger_chip_info(struct iosm_imem *ipc_imem)
-{
- return ipc_task_queue_send_task(ipc_imem,
- ipc_imem_devlink_trigger_chip_info_cb,
- 0, NULL, 0, true);
-}
@@ -69,7 +69,7 @@ struct ipc_chnl_cfg;
#define IMEM_IRQ_DONT_CARE (-1)
-#define IPC_MEM_MAX_CHANNELS 8
+#define IPC_MEM_MAX_CHANNELS 7
#define IPC_MEM_MUX_IP_SESSION_ENTRIES 8
@@ -98,7 +98,6 @@ struct ipc_chnl_cfg;
#define IPC_MEM_DL_ETH_OFFSET 16
#define IPC_CB(skb) ((struct ipc_skb_cb *)((skb)->cb))
-#define IOSM_CHIP_INFO_SIZE_MAX 100
#define FULLY_FUNCTIONAL 0
@@ -305,9 +304,9 @@ enum ipc_phase {
* @ipc_port: IPC PORT data structure pointer
* @pcie: IPC PCIe
* @dev: Pointer to device structure
+ * @flash_channel_id: Reserved channel id for flashing to RAM.
* @ipc_requested_state: Expected IPC state on CP.
* @channels: Channel list with UL/DL pipe pairs.
- * @ipc_devlink: IPC Devlink data structure pointer
* @ipc_status: local ipc_status
* @nr_of_channels: number of configured channels
* @startup_timer: startup timer for NAND support.
@@ -350,9 +349,9 @@ struct iosm_imem {
struct iosm_cdev *ipc_port[IPC_MEM_MAX_CHANNELS];
struct iosm_pcie *pcie;
struct device *dev;
+ int flash_channel_id;
enum ipc_mem_device_ipc_state ipc_requested_state;
struct ipc_mem_channel channels[IPC_MEM_MAX_CHANNELS];
- struct iosm_devlink *ipc_devlink;
u32 ipc_status;
u32 nr_of_channels;
struct hrtimer startup_timer;
@@ -576,15 +575,4 @@ void ipc_imem_ipc_init_check(struct iosm_imem *ipc_imem);
*/
void ipc_imem_channel_init(struct iosm_imem *ipc_imem, enum ipc_ctype ctype,
struct ipc_chnl_cfg chnl_cfg, u32 irq_moderation);
-
-/**
- * ipc_imem_devlink_trigger_chip_info - Inform devlink that the chip
- * information are available if the
- * flashing to RAM interworking shall be
- * executed.
- * @ipc_imem: Pointer to imem structure
- *
- * Returns: 0 on success, -1 on failure
- */
-int ipc_imem_devlink_trigger_chip_info(struct iosm_imem *ipc_imem);
#endif
@@ -6,7 +6,6 @@
#include <linux/delay.h>
#include "iosm_ipc_chnl_cfg.h"
-#include "iosm_ipc_devlink.h"
#include "iosm_ipc_imem.h"
#include "iosm_ipc_imem_ops.h"
#include "iosm_ipc_port.h"
@@ -332,319 +331,3 @@ int ipc_imem_sys_cdev_write(struct iosm_cdev *ipc_cdev, struct sk_buff *skb)
out:
return ret;
}
-
-/* Open a SIO link to CP and return the channel instance */
-struct ipc_mem_channel *ipc_imem_sys_devlink_open(struct iosm_imem *ipc_imem)
-{
- struct ipc_mem_channel *channel;
- enum ipc_phase phase;
- int channel_id;
-
- phase = ipc_imem_phase_update(ipc_imem);
- switch (phase) {
- case IPC_P_OFF:
- case IPC_P_ROM:
- /* Get a channel id as flash id and reserve it. */
- channel_id = ipc_imem_channel_alloc(ipc_imem,
- IPC_MEM_CTRL_CHL_ID_7,
- IPC_CTYPE_CTRL);
-
- if (channel_id < 0) {
- dev_err(ipc_imem->dev,
- "reservation of a flash channel id failed");
- goto error;
- }
-
- ipc_imem->ipc_devlink->devlink_sio.channel_id = channel_id;
- channel = &ipc_imem->channels[channel_id];
-
- /* Enqueue chip info data to be read */
- if (ipc_imem_devlink_trigger_chip_info(ipc_imem)) {
- dev_err(ipc_imem->dev, "Enqueue of chip info failed");
- channel->state = IMEM_CHANNEL_FREE;
- goto error;
- }
-
- return channel;
-
- case IPC_P_PSI:
- case IPC_P_EBL:
- ipc_imem->cp_version = ipc_mmio_get_cp_version(ipc_imem->mmio);
- if (ipc_imem->cp_version == -1) {
- dev_err(ipc_imem->dev, "invalid CP version");
- goto error;
- }
-
- channel_id = ipc_imem->ipc_devlink->devlink_sio.channel_id;
- return ipc_imem_channel_open(ipc_imem, channel_id,
- IPC_HP_CDEV_OPEN);
-
- default:
- /* CP is in the wrong state (e.g. CRASH or CD_READY) */
- dev_err(ipc_imem->dev, "SIO open refused, phase %d", phase);
- }
-error:
- return NULL;
-}
-
-/* Release a SIO channel link to CP. */
-void ipc_imem_sys_devlink_close(struct iosm_devlink *ipc_devlink)
-{
- struct iosm_imem *ipc_imem = ipc_devlink->pcie->imem;
- int boot_check_timeout = BOOT_CHECK_DEFAULT_TIMEOUT;
- enum ipc_mem_exec_stage exec_stage;
- struct ipc_mem_channel *channel;
- enum ipc_phase curr_phase;
- int status = 0;
- u32 tail = 0;
-
- channel = ipc_imem->ipc_devlink->devlink_sio.channel;
- curr_phase = ipc_imem->phase;
- /* Increase the total wait time to boot_check_timeout */
- do {
- exec_stage = ipc_mmio_get_exec_stage(ipc_imem->mmio);
- if (exec_stage == IPC_MEM_EXEC_STAGE_RUN ||
- exec_stage == IPC_MEM_EXEC_STAGE_PSI)
- break;
- msleep(20);
- boot_check_timeout -= 20;
- } while (boot_check_timeout > 0);
-
- /* If there are any pending TDs then wait for Timeout/Completion before
- * closing pipe.
- */
- if (channel->ul_pipe.old_tail != channel->ul_pipe.old_head) {
- status = wait_for_completion_interruptible_timeout
- (&ipc_imem->ul_pend_sem,
- msecs_to_jiffies(IPC_PEND_DATA_TIMEOUT));
- if (status == 0) {
- dev_dbg(ipc_imem->dev,
- "Data Timeout on UL-Pipe:%d Head:%d Tail:%d",
- channel->ul_pipe.pipe_nr,
- channel->ul_pipe.old_head,
- channel->ul_pipe.old_tail);
- }
- }
-
- ipc_protocol_get_head_tail_index(ipc_imem->ipc_protocol,
- &channel->dl_pipe, NULL, &tail);
-
- if (tail != channel->dl_pipe.old_tail) {
- status = wait_for_completion_interruptible_timeout
- (&ipc_imem->dl_pend_sem,
- msecs_to_jiffies(IPC_PEND_DATA_TIMEOUT));
- if (status == 0) {
- dev_dbg(ipc_imem->dev,
- "Data Timeout on DL-Pipe:%d Head:%d Tail:%d",
- channel->dl_pipe.pipe_nr,
- channel->dl_pipe.old_head,
- channel->dl_pipe.old_tail);
- }
- }
-
- /* Due to wait for completion in messages, there is a small window
- * between closing the pipe and updating the channel is closed. In this
- * small window there could be HP update from Host Driver. Hence update
- * the channel state as CLOSING to aviod unnecessary interrupt
- * towards CP.
- */
- channel->state = IMEM_CHANNEL_CLOSING;
- /* Release the pipe resources */
- ipc_imem_pipe_cleanup(ipc_imem, &channel->ul_pipe);
- ipc_imem_pipe_cleanup(ipc_imem, &channel->dl_pipe);
-}
-
-void ipc_imem_sys_devlink_notify_rx(struct iosm_devlink *ipc_devlink,
- struct sk_buff *skb)
-{
- skb_queue_tail(&ipc_devlink->devlink_sio.rx_list, skb);
- complete(&ipc_devlink->devlink_sio.read_sem);
-}
-
-/* PSI transfer */
-static int ipc_imem_sys_psi_transfer(struct iosm_imem *ipc_imem,
- struct ipc_mem_channel *channel,
- unsigned char *buf, int count)
-{
- int psi_start_timeout = PSI_START_DEFAULT_TIMEOUT;
- enum ipc_mem_exec_stage exec_stage;
-
- dma_addr_t mapping = 0;
- int ret;
-
- ret = ipc_pcie_addr_map(ipc_imem->pcie, buf, count, &mapping,
- DMA_TO_DEVICE);
- if (ret)
- goto pcie_addr_map_fail;
-
- /* Save the PSI information for the CP ROM driver on the doorbell
- * scratchpad.
- */
- ipc_mmio_set_psi_addr_and_size(ipc_imem->mmio, mapping, count);
- ipc_doorbell_fire(ipc_imem->pcie, 0, IPC_MEM_EXEC_STAGE_BOOT);
-
- ret = wait_for_completion_interruptible_timeout
- (&channel->ul_sem,
- msecs_to_jiffies(IPC_PSI_TRANSFER_TIMEOUT));
-
- if (ret <= 0) {
- dev_err(ipc_imem->dev, "Failed PSI transfer to CP, Error-%d",
- ret);
- goto psi_transfer_fail;
- }
- /* If the PSI download fails, return the CP boot ROM exit code */
- if (ipc_imem->rom_exit_code != IMEM_ROM_EXIT_OPEN_EXT &&
- ipc_imem->rom_exit_code != IMEM_ROM_EXIT_CERT_EXT) {
- ret = (-1) * ((int)ipc_imem->rom_exit_code);
- goto psi_transfer_fail;
- }
-
- dev_dbg(ipc_imem->dev, "PSI image successfully downloaded");
-
- /* Wait psi_start_timeout milliseconds until the CP PSI image is
- * running and updates the execution_stage field with
- * IPC_MEM_EXEC_STAGE_PSI. Verify the execution stage.
- */
- do {
- exec_stage = ipc_mmio_get_exec_stage(ipc_imem->mmio);
-
- if (exec_stage == IPC_MEM_EXEC_STAGE_PSI)
- break;
-
- msleep(20);
- psi_start_timeout -= 20;
- } while (psi_start_timeout > 0);
-
- if (exec_stage != IPC_MEM_EXEC_STAGE_PSI)
- goto psi_transfer_fail; /* Unknown status of CP PSI process. */
-
- ipc_imem->phase = IPC_P_PSI;
-
- /* Enter the PSI phase. */
- dev_dbg(ipc_imem->dev, "execution_stage[%X] eq. PSI", exec_stage);
-
- /* Request the RUNNING state from CP and wait until it was reached
- * or timeout.
- */
- ipc_imem_ipc_init_check(ipc_imem);
-
- ret = wait_for_completion_interruptible_timeout
- (&channel->ul_sem, msecs_to_jiffies(IPC_PSI_TRANSFER_TIMEOUT));
- if (ret <= 0) {
- dev_err(ipc_imem->dev,
- "Failed PSI RUNNING state on CP, Error-%d", ret);
- goto psi_transfer_fail;
- }
-
- if (ipc_mmio_get_ipc_state(ipc_imem->mmio) !=
- IPC_MEM_DEVICE_IPC_RUNNING) {
- dev_err(ipc_imem->dev,
- "ch[%d] %s: unexpected CP IPC state %d, not RUNNING",
- channel->channel_id,
- ipc_imem_phase_get_string(ipc_imem->phase),
- ipc_mmio_get_ipc_state(ipc_imem->mmio));
-
- goto psi_transfer_fail;
- }
-
- /* Create the flash channel for the transfer of the images. */
- if (!ipc_imem_sys_devlink_open(ipc_imem)) {
- dev_err(ipc_imem->dev, "can't open flash_channel");
- goto psi_transfer_fail;
- }
-
- ret = 0;
-psi_transfer_fail:
- ipc_pcie_addr_unmap(ipc_imem->pcie, count, mapping, DMA_TO_DEVICE);
-pcie_addr_map_fail:
- return ret;
-}
-
-int ipc_imem_sys_devlink_write(struct iosm_devlink *ipc_devlink,
- unsigned char *buf, int count)
-{
- struct iosm_imem *ipc_imem = ipc_devlink->pcie->imem;
- struct ipc_mem_channel *channel;
- struct sk_buff *skb;
- dma_addr_t mapping;
- int ret;
-
- channel = ipc_imem->ipc_devlink->devlink_sio.channel;
-
- /* In the ROM phase the PSI image is passed to CP about a specific
- * shared memory area and doorbell scratchpad directly.
- */
- if (ipc_imem->phase == IPC_P_ROM) {
- ret = ipc_imem_sys_psi_transfer(ipc_imem, channel, buf, count);
- /* If the PSI transfer fails then send crash
- * Signature.
- */
- if (ret > 0)
- ipc_imem_msg_send_feature_set(ipc_imem,
- IPC_MEM_INBAND_CRASH_SIG,
- false);
- goto out;
- }
-
- /* Allocate skb memory for the uplink buffer. */
- skb = ipc_pcie_alloc_skb(ipc_devlink->pcie, count, GFP_KERNEL, &mapping,
- DMA_TO_DEVICE, 0);
- if (!skb) {
- ret = -ENOMEM;
- goto out;
- }
-
- memcpy(skb_put(skb, count), buf, count);
-
- IPC_CB(skb)->op_type = UL_USR_OP_BLOCKED;
-
- /* Add skb to the uplink skbuf accumulator. */
- skb_queue_tail(&channel->ul_list, skb);
-
- /* Inform the IPC tasklet to pass uplink IP packets to CP. */
- if (!ipc_imem_call_cdev_write(ipc_imem)) {
- ret = wait_for_completion_interruptible(&channel->ul_sem);
-
- if (ret < 0) {
- dev_err(ipc_imem->dev,
- "ch[%d] no CP confirmation, status = %d",
- channel->channel_id, ret);
- ipc_pcie_kfree_skb(ipc_devlink->pcie, skb);
- goto out;
- }
- }
- ret = 0;
-out:
- return ret;
-}
-
-int ipc_imem_sys_devlink_read(struct iosm_devlink *devlink, u8 *data,
- u32 bytes_to_read, u32 *bytes_read)
-{
- struct sk_buff *skb = NULL;
- int rc = 0;
-
- /* check skb is available in rx_list or wait for skb */
- devlink->devlink_sio.devlink_read_pend = 1;
- while (!skb && !(skb = skb_dequeue(&devlink->devlink_sio.rx_list))) {
- if (!wait_for_completion_interruptible_timeout
- (&devlink->devlink_sio.read_sem,
- msecs_to_jiffies(IPC_READ_TIMEOUT))) {
- dev_err(devlink->dev, "Read timedout");
- rc = -ETIMEDOUT;
- goto devlink_read_fail;
- }
- }
- devlink->devlink_sio.devlink_read_pend = 0;
- if (bytes_to_read < skb->len) {
- dev_err(devlink->dev, "Invalid size,expected len %d", skb->len);
- rc = -EINVAL;
- goto devlink_read_fail;
- }
- *bytes_read = skb->len;
- memcpy(data, skb->data, skb->len);
-
-devlink_read_fail:
- ipc_pcie_kfree_skb(devlink->pcie, skb);
- return rc;
-}
@@ -9,7 +9,7 @@
#include "iosm_ipc_mux_codec.h"
/* Maximum wait time for blocking read */
-#define IPC_READ_TIMEOUT 3000
+#define IPC_READ_TIMEOUT 500
/* The delay in ms for defering the unregister */
#define SIO_UNREGISTER_DEFER_DELAY_MS 1
@@ -98,51 +98,4 @@ int ipc_imem_sys_wwan_transmit(struct iosm_imem *ipc_imem, int if_id,
*/
void ipc_imem_wwan_channel_init(struct iosm_imem *ipc_imem,
enum ipc_mux_protocol mux_type);
-
-/**
- * ipc_imem_sys_devlink_open - Open a Flash/CD Channel link to CP
- * @ipc_imem: iosm_imem instance
- *
- * Return: channel instance on success, NULL for failure
- */
-struct ipc_mem_channel *ipc_imem_sys_devlink_open(struct iosm_imem *ipc_imem);
-
-/**
- * ipc_imem_sys_devlink_close - Release a Flash/CD channel link to CP
- * @ipc_devlink: Pointer to ipc_devlink data-struct
- *
- */
-void ipc_imem_sys_devlink_close(struct iosm_devlink *ipc_devlink);
-
-/**
- * ipc_imem_sys_devlink_notify_rx - Receive downlink characters from CP,
- * the downlink skbuf is added at the end of the
- * downlink or rx list
- * @ipc_devlink: Pointer to ipc_devlink data-struct
- * @skb: Pointer to sk buffer
- */
-void ipc_imem_sys_devlink_notify_rx(struct iosm_devlink *ipc_devlink,
- struct sk_buff *skb);
-
-/**
- * ipc_imem_sys_devlink_read - Copy the rx data and free the skbuf
- * @ipc_devlink: Devlink instance
- * @data: Buffer to read the data from modem
- * @bytes_to_read: Size of destination buffer
- * @bytes_read: Number of bytes read
- *
- * Return: 0 on success and failure value on error
- */
-int ipc_imem_sys_devlink_read(struct iosm_devlink *ipc_devlink, u8 *data,
- u32 bytes_to_read, u32 *bytes_read);
-
-/**
- * ipc_imem_sys_devlink_write - Route the uplink buffer to CP
- * @ipc_devlink: Devlink_sio instance
- * @buf: Pointer to buffer
- * @count: Number of data bytes to write
- * Return: 0 on success and failure value on error
- */
-int ipc_imem_sys_devlink_write(struct iosm_devlink *ipc_devlink,
- unsigned char *buf, int count);
#endif
The devlink parameters are not the right mechanism to pass extra parameters to device flashing. The params added are also undocumented. This reverts commit 13bb8429ca98 ("net: wwan: iosm: firmware flashing and coredump collection"). Signed-off-by: Jakub Kicinski <kuba@kernel.org> --- drivers/net/wwan/Kconfig | 1 - drivers/net/wwan/iosm/Makefile | 5 +- drivers/net/wwan/iosm/iosm_ipc_chnl_cfg.c | 6 +- drivers/net/wwan/iosm/iosm_ipc_chnl_cfg.h | 1 - drivers/net/wwan/iosm/iosm_ipc_coredump.c | 110 ----- drivers/net/wwan/iosm/iosm_ipc_coredump.h | 75 --- drivers/net/wwan/iosm/iosm_ipc_devlink.c | 360 -------------- drivers/net/wwan/iosm/iosm_ipc_devlink.h | 207 -------- drivers/net/wwan/iosm/iosm_ipc_flash.c | 562 ---------------------- drivers/net/wwan/iosm/iosm_ipc_flash.h | 271 ----------- drivers/net/wwan/iosm/iosm_ipc_imem.c | 103 +--- drivers/net/wwan/iosm/iosm_ipc_imem.h | 18 +- drivers/net/wwan/iosm/iosm_ipc_imem_ops.c | 317 ------------ drivers/net/wwan/iosm/iosm_ipc_imem_ops.h | 49 +- 14 files changed, 31 insertions(+), 2054 deletions(-) delete mode 100644 drivers/net/wwan/iosm/iosm_ipc_coredump.c delete mode 100644 drivers/net/wwan/iosm/iosm_ipc_coredump.h delete mode 100644 drivers/net/wwan/iosm/iosm_ipc_devlink.c delete mode 100644 drivers/net/wwan/iosm/iosm_ipc_devlink.h delete mode 100644 drivers/net/wwan/iosm/iosm_ipc_flash.c delete mode 100644 drivers/net/wwan/iosm/iosm_ipc_flash.h