[NEUS7920-218] wlbt: record FW ttid and print in /proc
authorIvan Priest <i.priest@samsung.com>
Fri, 26 Apr 2019 15:47:28 +0000 (16:47 +0100)
committerKim Gunho <gunho.kim@samsung.com>
Fri, 28 Jun 2019 14:45:12 +0000 (23:45 +0900)
Read the traceability ID from FW header,
log in kernel and add a /proc handler

Change-Id: I85883852e9568680c7af950958140094c6b45ddf
SCSC-Bug-Id: SSB-52053
Signed-off-by: Ivan Priest <i.priest@samsung.com>
drivers/misc/samsung/scsc/fwhdr.c
drivers/misc/samsung/scsc/fwhdr.h
drivers/misc/samsung/scsc/mxman.c
drivers/misc/samsung/scsc/mxman.h
drivers/misc/samsung/scsc/mxproc.c

index 0600ebb6b1740e0bd7e6080184fcf7d398329444..f7d691415e41915ec032ad3c073d87c97a303b39 100644 (file)
@@ -28,6 +28,8 @@
 #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
  */
@@ -80,6 +82,15 @@ static char *fwhdr_get_build_id_v02(char *fw, struct fwhdr *fwhdr)
        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);
@@ -90,3 +101,7 @@ char *fwhdr_get_build_id(char *fw, struct fwhdr *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);
+}
index 115a81cc56f4ae8a9d6086b2c3eb7383f6166561..507b5695ff57a5e7803896c2a0cc9d534ca1a361 100644 (file)
@@ -8,6 +8,7 @@
 #define FWHDR_H
 
 #define FW_BUILD_ID_SZ 128
+#define FW_TTID_SZ     32
 
 struct fwhdr {
        u16 hdr_major;
@@ -31,5 +32,6 @@ struct fwhdr {
 
 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 */
index fb506f5efe963c505b4c5682f5623178ed69e581..fd316e8c7457a94868eb7e219edf2d6404251553 100755 (executable)
@@ -952,6 +952,7 @@ static int fw_init(struct mxman *mxman, void *start_dram, size_t size_dram, bool
 {
        int                 r;
        char                *build_id;
+       char                *ttid;
        u32                 fw_image_size;
        struct fwhdr        *fwhdr = &mxman->fwhdr;
        char                *fw = start_dram;
@@ -1001,6 +1002,12 @@ static int fw_init(struct mxman *mxman, void *start_dram, size_t size_dram, bool
                        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);
@@ -2001,6 +2008,7 @@ void mxman_init(struct mxman *mxman, struct scsc_mx *mx)
        (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;
 
index 12afc87071acd654568259984fd4396ea705a223..41cf750b5d8de150813a3ced9e02857e5ad4a2e8 100755 (executable)
@@ -84,6 +84,7 @@ struct 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);
index 464aa3c00b3e5444820f2f9df28fac0b231c9f37..547ff9b88a2920685a0a8e876ddb9a0a8ead615f 100644 (file)
@@ -486,6 +486,30 @@ static ssize_t mx_procfs_mx_release_read(struct file *file, char __user *user_bu
 
 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];
@@ -506,6 +530,7 @@ int mxproc_create_info_proc_dir(struct mxproc *mxproc, struct mxman *mxman)
        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;
@@ -516,6 +541,7 @@ void mxproc_remove_info_proc_dir(struct mxproc *mxproc)
        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);