/**************************************************************************** * * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved * ****************************************************************************/ #ifndef __SCSC_LOG_COLLECTOR_H__ #define __SCSC_LOG_COLLECTOR_H__ /* High nibble is Major, Low nibble is Minor */ #define SCSC_LOG_HEADER_VERSION_MAJOR 0x03 #define SCSC_LOG_HEADER_VERSION_MINOR 0x00 /* Magic string. 4 bytes "SCSC"*/ /* Header version. 1 byte */ /* Num chunks. 1 byte */ /* Offset first Chunk. 2 bytes */ /* Collection reason. 1 byte */ /* Reserved. 1 byte */ /* Reason Code . 2 bytes */ /* Observer present . 1 bytes */ #define SCSC_LOG_HEADER_SIZE (13) #define SCSC_LOG_FW_VERSION_SIZE (128) #define SCSC_LOG_HOST_VERSION_SIZE (64) #define SCSC_LOG_FAPI_VERSION_SIZE (64) /* Reserved 2 . 4 byte */ #define SCSC_LOG_RESERVED_2 3 /* Ideally header + versions should be 16 bytes aligne*/ #define SCSC_SUPPORTED_CHUNKS_HEADER 48 #define SCSC_LOG_CHUNK_ALIGN 1 /* First chunk should be aligned */ #define SCSC_LOG_OFFSET_FIRST_CHUNK (((SCSC_LOG_HEADER_SIZE + SCSC_LOG_FW_VERSION_SIZE + \ SCSC_LOG_HOST_VERSION_SIZE + SCSC_LOG_FAPI_VERSION_SIZE + \ SCSC_LOG_RESERVED_2 + SCSC_SUPPORTED_CHUNKS_HEADER) + \ (SCSC_LOG_CHUNK_ALIGN - 1)) & ~(SCSC_LOG_CHUNK_ALIGN - 1)) enum scsc_log_reason { SCSC_LOG_UNKNOWN = 0, SCSC_LOG_FW_PANIC, SCSC_LOG_USER, SCSC_LOG_FW, SCSC_LOG_DUMPSTATE, SCSC_LOG_HOST_WLAN, SCSC_LOG_HOST_BT, SCSC_LOG_HOST_COMMON, SCSC_LOG_SYS_ERR, /* Add others */ }; extern const char *scsc_loc_reason_str[]; #define SCSC_CHUNK_DAT_LEN_SIZE 4 #define SCSC_CHUNK_TYP_LEN_SIZE 4 #define SCSC_CHUNK_HEADER_SIZE (SCSC_CHUNK_DAT_LEN_SIZE + SCSC_CHUNK_TYP_LEN_SIZE) /* CHUNKS WILL COLLECTED ON THIS ORDER - * SYNC SHOULD BE THE FIRST CHUNK * LOGRING SHOULD BE THE LAST ONE SO IT COULD CAPTURE COLLECTION ERRORS */ enum scsc_log_chunk_type { SCSC_LOG_CHUNK_SYNC, /* SYNC should be the first chunk to collect */ SCSC_LOG_MINIMOREDUMP, /* Add other chunks */ SCSC_LOG_CHUNK_IMP = 127, SCSC_LOG_CHUNK_MXL, SCSC_LOG_CHUNK_UDI, SCSC_LOG_CHUNK_BT_HCF, SCSC_LOG_CHUNK_WLAN_HCF, SCSC_LOG_CHUNK_HIP4_SAMPLER, SCSC_LOG_RESERVED_COMMON, SCSC_LOG_RESERVED_BT, SCSC_LOG_RESERVED_WLAN, SCSC_LOG_RESERVED_RADIO, /* Add other chunks */ SCSC_LOG_CHUNK_LOGRING = 254, SCSC_LOG_CHUNK_INVALID = 255, }; #define SCSC_LOG_COLLECT_MAX_SIZE (16*1024*1024) /* ADD Collection codes here for HOST triggers */ /* Consider moving the definitions to specific services if required */ /* Reason codes for SCSC_LOG_USER */ #define SCSC_LOG_USER_REASON_PROC 0x0000 /* Reason codes for SCSC_LOG_DUMPSTATE */ #define SCSC_LOG_DUMPSTATE_REASON 0x0000 #define SCSC_LOG_DUMPSTATE_REASON_DRIVERDEBUGDUMP 0x0001 /* Reason codes for SCSC_LOG_HOST_WLAN */ #define SCSC_LOG_HOST_WLAN_REASON_DISCONNECT 0x0000 #define SCSC_LOG_HOST_WLAN_REASON_DISCONNECT_IND 0x0001 #define SCSC_LOG_HOST_WLAN_REASON_DISCONNECTED_IND 0x0002 #define SCSC_LOG_HOST_WLAN_REASON_DRIVERDEBUGDUMP 0x0003 #define SCSC_LOG_HOST_WLAN_REASON_CONNECT_ERR 0x0004 #define SCSC_LOG_HOST_WLAN_REASON_INVALID_AMSDU 0x0005 /* Reason codes for SCSC_LOG_HOST_BT */ #define SCSC_LOG_HOST_BT_REASON_HCI_ERROR 0x0000 /* Reason codes for SCSC_LOG_HOST_COMMON */ #define SCSC_LOG_HOST_COMMON_REASON_START 0x0000 #define SCSC_LOG_HOST_COMMON_REASON_STOP 0x0001 #define SCSC_LOG_HOST_COMMON_RECOVER_RST 0x0002 /* SBL HEADER v 0.0*/ struct scsc_log_sbl_header { char magic[4]; u8 version_major; u8 version_minor; u8 num_chunks; u8 trigger; u16 offset_data; char fw_version[SCSC_LOG_FW_VERSION_SIZE]; char host_version[SCSC_LOG_HOST_VERSION_SIZE]; char fapi_version[SCSC_LOG_FAPI_VERSION_SIZE]; u16 reason_code; bool observer; u8 reserved2[SCSC_LOG_RESERVED_2]; char supported_chunks[SCSC_SUPPORTED_CHUNKS_HEADER]; } __packed; struct scsc_log_chunk_header { char magic[3]; u8 type; u32 chunk_size; } __packed; struct scsc_log_collector_client { char *name; enum scsc_log_chunk_type type; int (*collect_init)(struct scsc_log_collector_client *collect_client); int (*collect)(struct scsc_log_collector_client *collect_client, size_t size); int (*collect_end)(struct scsc_log_collector_client *collect_client); void *prv; }; int scsc_log_collector_register_client(struct scsc_log_collector_client *collect_client); int scsc_log_collector_unregister_client(struct scsc_log_collector_client *collect_client); /* Public method to get pointer of SBL RAM buffer. */ unsigned char *scsc_log_collector_get_buffer(void); /* Public method to register FAPI version. */ void scsc_log_collector_write_fapi(char __user *buf, size_t len); /* Public method to notify the presence/absense of observers */ void scsc_log_collector_is_observer(bool observer); void scsc_log_collector_schedule_collection(enum scsc_log_reason reason, u16 reason_code); int scsc_log_collector_write(char __user *buf, size_t count, u8 align); /* function to provide string representation of uint8 trigger code */ static inline const char *scsc_get_trigger_str(int code) { switch (code) { case 1: return "scsc_log_fw_panic"; case 2: return "scsc_log_user"; case 3: return "scsc_log_fw"; case 4: return "scsc_log_dumpstate"; case 5: return "scsc_log_host_wlan"; case 6: return "scsc_log_host_bt"; case 7: return "scsc_log_host_common"; case 8: return "scsc_log_sys_error"; case 0: default: return "unknown"; } }; /* callbacks to mxman */ struct scsc_log_collector_mx_cb { void (*get_fw_version)(struct scsc_log_collector_mx_cb *mx_cb, char *version, size_t ver_sz); void (*get_drv_version)(struct scsc_log_collector_mx_cb *mx_cb, char *version, size_t ver_sz); void (*call_wlbtd_sable)(struct scsc_log_collector_mx_cb *mx_cb, u8 trigger_code, u16 reason_code); }; int scsc_log_collector_register_mx_cb(struct scsc_log_collector_mx_cb *mx_cb); int scsc_log_collector_unregister_mx_cb(struct scsc_log_collector_mx_cb *mx_cb); #endif /* __SCSC_LOG_COLLECTOR_H__ */