Commit b8aa1654 authored by M Chetan Kumar's avatar M Chetan Kumar Committed by David S. Miller

net: wwan: iosm: correct devlink extra params

1. Removed driver specific extra params like download_region,
   address & region_count. The required information is passed
   as part of flash API.
2. IOSM Devlink documentation updated to reflect the same.
Signed-off-by: default avatarM Chetan Kumar <m.chetan.kumar@linux.intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e9637775
...@@ -26,23 +26,6 @@ The ``iosm`` driver implements the following driver-specific parameters. ...@@ -26,23 +26,6 @@ The ``iosm`` driver implements the following driver-specific parameters.
the device during firmware flashing. the device during firmware flashing.
If set, Full nand erase command will be sent to the device. By default, If set, Full nand erase command will be sent to the device. By default,
only conditional erase support is enabled. only conditional erase support is enabled.
* - ``download_region``
- u8
- runtime
- download_region parameter is used to identify if we are flashing the
loadmap/region file during the firmware flashing.
* - ``address``
- u32
- runtime
- address parameter is used to send the address information of the
loadmap/region file which is required during the firmware flashing
process. Each region file has be flashed to its respective flash address.
* - ``region_count``
- u8
- runtime
- region_count parameter is used to inform the driver on how many total
loadmap/region files are present in modem firmware image that has to be
flashed.
Flash Update Flash Update
...@@ -87,7 +70,7 @@ Flash Commands: ...@@ -87,7 +70,7 @@ Flash Commands:
1) When modem is in Boot ROM stage, user can use below command to inject PSI RAM 1) When modem is in Boot ROM stage, user can use below command to inject PSI RAM
image using devlink flash command. image using devlink flash command.
$ devlink dev flash pci/0000:02:00.0 file <PSI_RAM_File_name> component PSI $ devlink dev flash pci/0000:02:00.0 file <PSI_RAM_File_name>
2) If user want to do a full erase, below command need to be issued to set the 2) If user want to do a full erase, below command need to be issued to set the
erase full flash param (To be set only if full erase required). erase full flash param (To be set only if full erase required).
...@@ -95,22 +78,19 @@ erase full flash param (To be set only if full erase required). ...@@ -95,22 +78,19 @@ erase full flash param (To be set only if full erase required).
$ devlink dev param set pci/0000:02:00.0 name erase_full_flash value true cmode runtime $ devlink dev param set pci/0000:02:00.0 name erase_full_flash value true cmode runtime
3) Inject EBL after the modem is in PSI stage. 3) Inject EBL after the modem is in PSI stage.
$ devlink dev flash pci/0000:02:00.0 file <EBL_File_name> component EBL
$ devlink dev flash pci/0000:02:00.0 file <EBL_File_name>
4) Once EBL is injected successfully, then the actual firmware flashing takes 4) Once EBL is injected successfully, then the actual firmware flashing takes
place. Below is the sequence of commands used for each of the firmware images. place. Below is the sequence of commands used for each of the firmware images.
a) Flash secure bin file. a) Flash secure bin file.
$ devlink dev flash pci/0000:02:00.0 file <Secure_bin_file_name> component FLS
b) Flashing the Loadmap/Region file
$ devlink dev param set pci/0000:02:00.0 name region_count value 1 cmode runtime
$ devlink dev param set pci/0000:02:00.0 name download_region value true cmode runtime $ devlink dev flash pci/0000:02:00.0 file <Secure_bin_file_name>
$ devlink dev param set pci/0000:02:00.0 name address value <Nand_address> cmode runtime b) Flashing the Loadmap/Region file
$ devlink dev flash pci/0000:02:00.0 file <Load_map_file_name> component FLS $ devlink dev flash pci/0000:02:00.0 file <Load_map_file_name>
Regions Regions
======= =======
......
...@@ -23,31 +23,11 @@ static int ipc_devlink_get_param(struct devlink *dl, u32 id, ...@@ -23,31 +23,11 @@ static int ipc_devlink_get_param(struct devlink *dl, u32 id,
struct devlink_param_gset_ctx *ctx) struct devlink_param_gset_ctx *ctx)
{ {
struct iosm_devlink *ipc_devlink = devlink_priv(dl); struct iosm_devlink *ipc_devlink = devlink_priv(dl);
int rc = 0;
switch (id) { if (id == IOSM_DEVLINK_PARAM_ID_ERASE_FULL_FLASH)
case IOSM_DEVLINK_PARAM_ID_ERASE_FULL_FLASH:
ctx->val.vu8 = ipc_devlink->param.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: return 0;
rc = -EOPNOTSUPP;
break;
}
return rc;
} }
/* Set the param values for the specific param ID's */ /* Set the param values for the specific param ID's */
...@@ -55,31 +35,11 @@ static int ipc_devlink_set_param(struct devlink *dl, u32 id, ...@@ -55,31 +35,11 @@ static int ipc_devlink_set_param(struct devlink *dl, u32 id,
struct devlink_param_gset_ctx *ctx) struct devlink_param_gset_ctx *ctx)
{ {
struct iosm_devlink *ipc_devlink = devlink_priv(dl); struct iosm_devlink *ipc_devlink = devlink_priv(dl);
int rc = 0;
switch (id) { if (id == IOSM_DEVLINK_PARAM_ID_ERASE_FULL_FLASH)
case IOSM_DEVLINK_PARAM_ID_ERASE_FULL_FLASH:
ipc_devlink->param.erase_full_flash = ctx->val.vu8; 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; return 0;
} }
/* Devlink param structure array */ /* Devlink param structure array */
...@@ -89,21 +49,6 @@ static const struct devlink_param iosm_devlink_params[] = { ...@@ -89,21 +49,6 @@ static const struct devlink_param iosm_devlink_params[] = {
BIT(DEVLINK_PARAM_CMODE_RUNTIME), BIT(DEVLINK_PARAM_CMODE_RUNTIME),
ipc_devlink_get_param, ipc_devlink_set_param, ipc_devlink_get_param, ipc_devlink_set_param,
NULL), 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 */ /* Get devlink flash component type */
...@@ -134,18 +79,23 @@ static int ipc_devlink_flash_update(struct devlink *devlink, ...@@ -134,18 +79,23 @@ static int ipc_devlink_flash_update(struct devlink *devlink,
{ {
struct iosm_devlink *ipc_devlink = devlink_priv(devlink); struct iosm_devlink *ipc_devlink = devlink_priv(devlink);
enum iosm_flash_comp_type fls_type; enum iosm_flash_comp_type fls_type;
struct iosm_devlink_image *header;
int rc = -EINVAL; int rc = -EINVAL;
u8 *mdm_rsp; u8 *mdm_rsp;
if (!params->component) header = (struct iosm_devlink_image *)params->fw->data;
if (!header || params->fw->size <= IOSM_DEVLINK_HDR_SIZE ||
(memcmp(header->magic_header, IOSM_DEVLINK_MAGIC_HEADER,
IOSM_DEVLINK_MAGIC_HEADER_LEN) != 0))
return -EINVAL; return -EINVAL;
mdm_rsp = kzalloc(IOSM_EBL_DW_PACK_SIZE, GFP_KERNEL); mdm_rsp = kzalloc(IOSM_EBL_DW_PACK_SIZE, GFP_KERNEL);
if (!mdm_rsp) if (!mdm_rsp)
return -ENOMEM; return -ENOMEM;
fls_type = ipc_devlink_get_flash_comp_type(params->component, fls_type = ipc_devlink_get_flash_comp_type(header->image_type,
strlen(params->component)); IOSM_DEVLINK_MAX_IMG_LEN);
switch (fls_type) { switch (fls_type) {
case FLASH_COMP_TYPE_PSI: case FLASH_COMP_TYPE_PSI:
...@@ -165,16 +115,16 @@ static int ipc_devlink_flash_update(struct devlink *devlink, ...@@ -165,16 +115,16 @@ static int ipc_devlink_flash_update(struct devlink *devlink,
break; break;
default: default:
devlink_flash_update_status_notify(devlink, "Invalid component", devlink_flash_update_status_notify(devlink, "Invalid component",
params->component, 0, 0); NULL, 0, 0);
break; break;
} }
if (!rc) if (!rc)
devlink_flash_update_status_notify(devlink, "Flashing success", devlink_flash_update_status_notify(devlink, "Flashing success",
params->component, 0, 0); header->image_type, 0, 0);
else else
devlink_flash_update_status_notify(devlink, "Flashing failed", devlink_flash_update_status_notify(devlink, "Flashing failed",
params->component, 0, 0); header->image_type, 0, 0);
kfree(mdm_rsp); kfree(mdm_rsp);
return rc; return rc;
...@@ -182,7 +132,6 @@ static int ipc_devlink_flash_update(struct devlink *devlink, ...@@ -182,7 +132,6 @@ static int ipc_devlink_flash_update(struct devlink *devlink,
/* Call back function for devlink ops */ /* Call back function for devlink ops */
static const struct devlink_ops devlink_flash_ops = { static const struct devlink_ops devlink_flash_ops = {
.supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT,
.flash_update = ipc_devlink_flash_update, .flash_update = ipc_devlink_flash_update,
}; };
......
...@@ -12,6 +12,18 @@ ...@@ -12,6 +12,18 @@
#include "iosm_ipc_imem_ops.h" #include "iosm_ipc_imem_ops.h"
#include "iosm_ipc_pcie.h" #include "iosm_ipc_pcie.h"
/* Image ext max len */
#define IOSM_DEVLINK_MAX_IMG_LEN 3
/* Magic Header */
#define IOSM_DEVLINK_MAGIC_HEADER "IOSM_DEVLINK_HEADER"
/* Magic Header len */
#define IOSM_DEVLINK_MAGIC_HEADER_LEN 20
/* Devlink image type */
#define IOSM_DEVLINK_IMG_TYPE 4
/* Reserve header size */
#define IOSM_DEVLINK_RESERVED 34
/* Devlink Image Header size */
#define IOSM_DEVLINK_HDR_SIZE sizeof(struct iosm_devlink_image)
/* MAX file name length */ /* MAX file name length */
#define IOSM_MAX_FILENAME_LEN 32 #define IOSM_MAX_FILENAME_LEN 32
/* EBL response size */ /* EBL response size */
...@@ -32,19 +44,11 @@ ...@@ -32,19 +44,11 @@
* enum iosm_devlink_param_id - Enum type to different devlink params * enum iosm_devlink_param_id - Enum type to different devlink params
* @IOSM_DEVLINK_PARAM_ID_BASE: Devlink param base ID * @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_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 { enum iosm_devlink_param_id {
IOSM_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX, IOSM_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
IOSM_DEVLINK_PARAM_ID_ERASE_FULL_FLASH, IOSM_DEVLINK_PARAM_ID_ERASE_FULL_FLASH,
IOSM_DEVLINK_PARAM_ID_DOWNLOAD_REGION,
IOSM_DEVLINK_PARAM_ID_ADDRESS,
IOSM_DEVLINK_PARAM_ID_REGION_COUNT,
}; };
/** /**
...@@ -94,22 +98,34 @@ struct iosm_devlink_sio { ...@@ -94,22 +98,34 @@ struct iosm_devlink_sio {
/** /**
* struct iosm_flash_params - List of flash params required for flashing * 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: To set the flashing mode
* erase_full_flash = 1; full erase * erase_full_flash = 1; full erase
* erase_full_flash = 0; no erase * erase_full_flash = 0; no erase
* @erase_full_flash_done: Flag to check if it is a full erase * @erase_full_flash_done: Flag to check if it is a full erase
*/ */
struct iosm_flash_params { struct iosm_flash_params {
u32 address;
u8 region_count;
u8 download_region;
u8 erase_full_flash; u8 erase_full_flash;
u8 erase_full_flash_done; u8 erase_full_flash_done;
}; };
/**
* struct iosm_devlink_image - Structure with Fls file header info
* @magic_header: Header of the firmware image
* @image_type: Firmware image type
* @region_address: Address of the region to be flashed
* @download_region: Field to identify if it is a region
* @last_region: Field to identify if it is last region
* @reserved: Reserved field
*/
struct iosm_devlink_image {
char magic_header[IOSM_DEVLINK_MAGIC_HEADER_LEN];
char image_type[IOSM_DEVLINK_IMG_TYPE];
__le32 region_address;
u8 download_region;
u8 last_region;
u8 reserved[IOSM_DEVLINK_RESERVED];
} __packed;
/** /**
* struct iosm_ebl_ctx_data - EBL ctx data used during flashing * struct iosm_ebl_ctx_data - EBL ctx data used during flashing
* @ebl_sw_info_version: SWID version info obtained from EBL * @ebl_sw_info_version: SWID version info obtained from EBL
......
...@@ -330,18 +330,20 @@ static int ipc_flash_full_erase(struct iosm_devlink *ipc_devlink, u8 *mdm_rsp) ...@@ -330,18 +330,20 @@ static int ipc_flash_full_erase(struct iosm_devlink *ipc_devlink, u8 *mdm_rsp)
static int ipc_flash_download_region(struct iosm_devlink *ipc_devlink, static int ipc_flash_download_region(struct iosm_devlink *ipc_devlink,
const struct firmware *fw, u8 *mdm_rsp) const struct firmware *fw, u8 *mdm_rsp)
{ {
u32 raw_len, rest_len = fw->size - IOSM_DEVLINK_HDR_SIZE;
struct iosm_devlink_image *fls_data;
__le32 reg_info[2]; /* 0th position region address, 1st position size */ __le32 reg_info[2]; /* 0th position region address, 1st position size */
u32 nand_address;
char *file_ptr; char *file_ptr;
u32 rest_len;
u32 raw_len;
int ret; int ret;
file_ptr = (char *)fw->data; fls_data = (struct iosm_devlink_image *)fw->data;
reg_info[0] = cpu_to_le32(ipc_devlink->param.address); file_ptr = (void *)(fls_data + 1);
nand_address = le32_to_cpu(fls_data->region_address);
reg_info[0] = cpu_to_le32(nand_address);
if (!ipc_devlink->param.erase_full_flash_done) { if (!ipc_devlink->param.erase_full_flash_done) {
reg_info[1] = cpu_to_le32(ipc_devlink->param.address + reg_info[1] = cpu_to_le32(nand_address + rest_len - 2);
fw->size - 2);
ret = ipc_flash_send_receive(ipc_devlink, FLASH_ERASE_START, ret = ipc_flash_send_receive(ipc_devlink, FLASH_ERASE_START,
(u8 *)reg_info, IOSM_MDM_SEND_8, (u8 *)reg_info, IOSM_MDM_SEND_8,
mdm_rsp); mdm_rsp);
...@@ -359,8 +361,6 @@ static int ipc_flash_download_region(struct iosm_devlink *ipc_devlink, ...@@ -359,8 +361,6 @@ static int ipc_flash_download_region(struct iosm_devlink *ipc_devlink,
if (ret) if (ret)
goto dl_region_fail; goto dl_region_fail;
rest_len = fw->size;
/* Request Flash Write Raw Image */ /* Request Flash Write Raw Image */
ret = ipc_flash_send_data(ipc_devlink, IOSM_EBL_DW_PACK_SIZE, ret = ipc_flash_send_data(ipc_devlink, IOSM_EBL_DW_PACK_SIZE,
FLASH_WRITE_IMAGE_RAW, (u8 *)&rest_len, FLASH_WRITE_IMAGE_RAW, (u8 *)&rest_len,
...@@ -399,9 +399,12 @@ static int ipc_flash_download_region(struct iosm_devlink *ipc_devlink, ...@@ -399,9 +399,12 @@ static int ipc_flash_download_region(struct iosm_devlink *ipc_devlink,
int ipc_flash_send_fls(struct iosm_devlink *ipc_devlink, int ipc_flash_send_fls(struct iosm_devlink *ipc_devlink,
const struct firmware *fw, u8 *mdm_rsp) const struct firmware *fw, u8 *mdm_rsp)
{ {
u32 fw_size = fw->size - IOSM_DEVLINK_HDR_SIZE;
struct iosm_devlink_image *fls_data;
u16 flash_cmd; u16 flash_cmd;
int ret; int ret;
fls_data = (struct iosm_devlink_image *)fw->data;
if (ipc_devlink->param.erase_full_flash) { if (ipc_devlink->param.erase_full_flash) {
ipc_devlink->param.erase_full_flash = false; ipc_devlink->param.erase_full_flash = false;
ret = ipc_flash_full_erase(ipc_devlink, mdm_rsp); ret = ipc_flash_full_erase(ipc_devlink, mdm_rsp);
...@@ -410,19 +413,20 @@ int ipc_flash_send_fls(struct iosm_devlink *ipc_devlink, ...@@ -410,19 +413,20 @@ int ipc_flash_send_fls(struct iosm_devlink *ipc_devlink,
} }
/* Request Sec Start */ /* Request Sec Start */
if (!ipc_devlink->param.download_region) { if (!fls_data->download_region) {
ret = ipc_flash_send_receive(ipc_devlink, FLASH_SEC_START, ret = ipc_flash_send_receive(ipc_devlink, FLASH_SEC_START,
(u8 *)fw->data, fw->size, mdm_rsp); (u8 *)fw->data +
IOSM_DEVLINK_HDR_SIZE, fw_size,
mdm_rsp);
if (ret) if (ret)
goto ipc_flash_err; goto ipc_flash_err;
} else { } else {
/* Download regions */ /* Download regions */
ipc_devlink->param.region_count -= IOSM_SET_FLAG;
ret = ipc_flash_download_region(ipc_devlink, fw, mdm_rsp); ret = ipc_flash_download_region(ipc_devlink, fw, mdm_rsp);
if (ret) if (ret)
goto ipc_flash_err; goto ipc_flash_err;
if (!ipc_devlink->param.region_count) { if (fls_data->last_region) {
/* Request Sec End */ /* Request Sec End */
flash_cmd = IOSM_MDM_SEND_DATA; flash_cmd = IOSM_MDM_SEND_DATA;
ret = ipc_flash_send_receive(ipc_devlink, FLASH_SEC_END, ret = ipc_flash_send_receive(ipc_devlink, FLASH_SEC_END,
...@@ -445,17 +449,18 @@ int ipc_flash_send_fls(struct iosm_devlink *ipc_devlink, ...@@ -445,17 +449,18 @@ int ipc_flash_send_fls(struct iosm_devlink *ipc_devlink,
int ipc_flash_boot_psi(struct iosm_devlink *ipc_devlink, int ipc_flash_boot_psi(struct iosm_devlink *ipc_devlink,
const struct firmware *fw) const struct firmware *fw)
{ {
u32 bytes_read, psi_size = fw->size - IOSM_DEVLINK_HDR_SIZE;
u8 psi_ack_byte[IOSM_PSI_ACK], read_data[2]; u8 psi_ack_byte[IOSM_PSI_ACK], read_data[2];
u32 bytes_read;
u8 *psi_code; u8 *psi_code;
int ret; int ret;
dev_dbg(ipc_devlink->dev, "Boot transfer PSI"); dev_dbg(ipc_devlink->dev, "Boot transfer PSI");
psi_code = kmemdup(fw->data, fw->size, GFP_KERNEL); psi_code = kmemdup(fw->data + IOSM_DEVLINK_HDR_SIZE, psi_size,
GFP_KERNEL);
if (!psi_code) if (!psi_code)
return -ENOMEM; return -ENOMEM;
ret = ipc_imem_sys_devlink_write(ipc_devlink, psi_code, fw->size); ret = ipc_imem_sys_devlink_write(ipc_devlink, psi_code, psi_size);
if (ret) { if (ret) {
dev_err(ipc_devlink->dev, "RPSI Image write failed"); dev_err(ipc_devlink->dev, "RPSI Image write failed");
goto ipc_flash_psi_free; goto ipc_flash_psi_free;
...@@ -501,7 +506,7 @@ int ipc_flash_boot_psi(struct iosm_devlink *ipc_devlink, ...@@ -501,7 +506,7 @@ int ipc_flash_boot_psi(struct iosm_devlink *ipc_devlink,
int ipc_flash_boot_ebl(struct iosm_devlink *ipc_devlink, int ipc_flash_boot_ebl(struct iosm_devlink *ipc_devlink,
const struct firmware *fw) const struct firmware *fw)
{ {
u32 ebl_size = fw->size; u32 ebl_size = fw->size - IOSM_DEVLINK_HDR_SIZE;
u8 read_data[2]; u8 read_data[2];
u32 bytes_read; u32 bytes_read;
int ret; int ret;
...@@ -553,8 +558,9 @@ int ipc_flash_boot_ebl(struct iosm_devlink *ipc_devlink, ...@@ -553,8 +558,9 @@ int ipc_flash_boot_ebl(struct iosm_devlink *ipc_devlink,
goto ipc_flash_ebl_err; goto ipc_flash_ebl_err;
} }
ret = ipc_imem_sys_devlink_write(ipc_devlink, (unsigned char *)fw->data, ret = ipc_imem_sys_devlink_write(ipc_devlink,
fw->size); (u8 *)fw->data + IOSM_DEVLINK_HDR_SIZE,
ebl_size);
if (ret) { if (ret) {
dev_err(ipc_devlink->dev, "EBL data transfer failed"); dev_err(ipc_devlink->dev, "EBL data transfer failed");
goto ipc_flash_ebl_err; goto ipc_flash_ebl_err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment