#define FWHDR_02_BUILD_ID_OFFSET 48
#define FWHDR_02_R4_PANIC_RECORD_OFFSET_OFFSET 176
#define FWHDR_02_M4_PANIC_RECORD_OFFSET_OFFSET 180
+#define FWHDR_02_TTID_OFFSET 184
+
/*
* Firmware header format for version 1.0 is same as version for 0.2
*/
return NULL;
}
+static char *fwhdr_get_ttid_v02(char *fw, struct fwhdr *fwhdr)
+{
+ if (fwhdr->hdr_length < FWHDR_02_TTID_OFFSET)
+ return NULL;
+ if (!memcmp(fw + FWHDR_02_MAGIC_OFFSET, FWHDR_MAGIC_STRING, sizeof(FWHDR_MAGIC_STRING) - 1))
+ return fw + FWHDR_02_TTID_OFFSET;
+ return NULL;
+}
+
bool fwhdr_parse(char *fw, struct fwhdr *fwhdr)
{
return fwhdr_parse_v02(fw, fwhdr);
return fwhdr_get_build_id_v02(fw, fwhdr);
}
+char *fwhdr_get_ttid(char *fw, struct fwhdr *fwhdr)
+{
+ return fwhdr_get_ttid_v02(fw, fwhdr);
+}
#define FWHDR_H
#define FW_BUILD_ID_SZ 128
+#define FW_TTID_SZ 32
struct fwhdr {
u16 hdr_major;
bool fwhdr_parse(char *fw, struct fwhdr *fwhdr);
char *fwhdr_get_build_id(char *fw, struct fwhdr *fwhdr);
+char *fwhdr_get_ttid(char *fw, struct fwhdr *fwhdr);
#endif /* FWHDR_H */
{
int r;
char *build_id;
+ char *ttid;
u32 fw_image_size;
struct fwhdr *fwhdr = &mxman->fwhdr;
char *fw = start_dram;
slsi_kic_service_information(slsi_kic_technology_type_common, &kic_info);
} else
SCSC_TAG_ERR(MXMAN, "Failed to get Firmware BUILD_ID\n");
+
+ ttid = fwhdr_get_ttid(fw, fwhdr);
+ if (ttid) {
+ (void)snprintf(mxman->fw_ttid, sizeof(mxman->fw_ttid), "%s", ttid);
+ SCSC_TAG_INFO(MXMAN, "Firmware ttid: %s\n", mxman->fw_ttid);
+ }
}
SCSC_TAG_DEBUG(MXMAN, "firmware_entry_point=0x%x fw_runtime_length=%d\n", fwhdr->firmware_entry_point, fwhdr->fw_runtime_length);
(void)snprintf(mxman->fw_build_id, sizeof(mxman->fw_build_id), "unknown");
memcpy(saved_fw_build_id, mxman->fw_build_id,
sizeof(saved_fw_build_id));
+ (void)snprintf(mxman->fw_ttid, sizeof(mxman->fw_ttid), "unknown");
mxproc_create_info_proc_dir(&mxman->mxproc, mxman);
active_mxman = mxman;
int fm_params_pending; /* FM freq info waiting to be delivered to FW */
#endif
char failure_reason[SCSC_FAILURE_REASON_LEN]; /* previous failure reason */
+ char fw_ttid[FW_TTID_SZ]; /* Defined in SC-505846-SW */
};
void mxman_register_gdb_channel(struct scsc_mx *mx, mxmgmt_channel_handler handler, void *data);
MX_PROCFS_RO_FILE_OPS(mx_release);
+static ssize_t mx_procfs_mx_ttid_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos)
+{
+ char buf[256];
+ int bytes;
+ struct mxproc *mxproc = file->private_data;
+ char *id = 0;
+
+ OS_UNUSED_PARAMETER(file);
+
+ if (mxproc && mxproc->mxman)
+ id = mxproc->mxman->fw_ttid;
+
+ memset(buf, '\0', sizeof(buf));
+
+ bytes = snprintf(buf, sizeof(buf), "%s\n", id);
+
+ if (bytes > sizeof(buf))
+ bytes = sizeof(buf);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, bytes);
+}
+
+MX_PROCFS_RO_FILE_OPS(mx_ttid);
+
int mxproc_create_info_proc_dir(struct mxproc *mxproc, struct mxman *mxman)
{
char dir[MX_DIRLEN];
MX_PROCFS_ADD_FILE(mxproc, mx_rf_hw_ver, parent, S_IRUSR | S_IRGRP | S_IROTH);
MX_PROCFS_ADD_FILE(mxproc, mx_rf_hw_name, parent, S_IRUSR | S_IRGRP | S_IROTH);
MX_PROCFS_ADD_FILE(mxproc, mx_boot_count, parent, S_IRUSR | S_IRGRP | S_IROTH);
+ MX_PROCFS_ADD_FILE(mxproc, mx_ttid, parent, S_IRUSR | S_IRGRP | S_IROTH);
SCSC_TAG_DEBUG(MX_PROC, "created %s proc dir\n", dir);
return 0;
if (mxproc->procfs_info_dir) {
char dir[MX_DIRLEN];
+ MX_PROCFS_REMOVE_FILE(mx_ttid, mxproc->procfs_ctrl_dir);
MX_PROCFS_REMOVE_FILE(mx_boot_count, mxproc->procfs_ctrl_dir);
MX_PROCFS_REMOVE_FILE(mx_release, mxproc->procfs_info_dir);
MX_PROCFS_REMOVE_FILE(mx_rf_hw_ver, mxproc->procfs_info_dir);