Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ad2844d8 authored by Ravi Aravamudhan's avatar Ravi Aravamudhan
Browse files

diag: dci: Extend DCI support to remote processors



DCI is now supported on the remote processors. Make changes to
the DCI logic in diag driver to allow clients to register with
remote processors for diag data.

Change-Id: I15dc4b63f2d8fa4e7a1f4f2307b25a5dcddfaa1a
Signed-off-by: default avatarRavi Aravamudhan <aravamud@codeaurora.org>
parent a18f488c
Loading
Loading
Loading
Loading
+799 −205

File changed.

Preview size limit exceeded, changes collapsed.

+81 −23
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#define MAX_DCI_CLIENTS		10
#define DCI_PKT_RSP_CODE	0x93
#define DCI_DELAYED_RSP_CODE	0x94
#define DCI_CONTROL_PKT_CODE	0x9A
#define LOG_CMD_CODE		0x10
#define EVENT_CMD_CODE		0x60
#define DCI_PKT_RSP_TYPE	0
@@ -49,13 +50,26 @@
#define DCI_MAX_LOG_CODES		16
#define DCI_MAX_ITEMS_PER_LOG_CODE	512

#define DCI_LOG_MASK_CLEAN		0
#define DCI_LOG_MASK_DIRTY		1

#define MIN_DELAYED_RSP_LEN		12
/*
 * Maximum data size that peripherals send = 8.5K log +
 * DCI header + footer (6 bytes)
 */
#define MAX_DCI_PACKET_SZ		8710

#define DCI_LOCAL_PROC	0
#define DCI_MDM_PROC	1

#define DCI_BRIDGE_MDM_IDX	1
#define DCI_HSIC_CH_IDX		0

#define DCI_REMOTE_DATA	0

extern unsigned int dci_max_reg;
extern unsigned int dci_max_clients;
extern unsigned char dci_cumulative_log_mask[DCI_LOG_MASK_SIZE];
extern unsigned char dci_cumulative_event_mask[DCI_EVENT_MASK_SIZE];
extern struct mutex dci_health_mutex;

struct dci_pkt_req_entry_t {
	int client_id;
@@ -68,7 +82,8 @@ struct diag_dci_reg_tbl_t {
	uint32_t client_id;
	uint16_t notification_list;
	int signal_type;
};
	int token;
} __packed;

struct diag_dci_health_t {
	int dropped_logs;
@@ -77,6 +92,14 @@ struct diag_dci_health_t {
	int received_events;
};

struct diag_dci_partial_pkt_t {
	unsigned char *data;
	uint32_t total_len;
	uint32_t read_len;
	uint32_t remaining;
	uint8_t processing;
} __packed;

struct diag_dci_buffer_t {
	unsigned char *data;
	unsigned int data_len;
@@ -105,7 +128,8 @@ struct diag_dci_client_tbl {
	unsigned char *dci_event_mask;
	uint8_t real_time;
	struct list_head track;
	struct diag_dci_buf_peripheral_t buffers[NUM_DCI_PROC];
	struct diag_dci_buf_peripheral_t *buffers;
	uint8_t num_buffers;
	uint8_t in_service;
	struct list_head list_write_buf;
	struct mutex write_buf_mutex;
@@ -120,7 +144,12 @@ struct diag_dci_health_stats_proc {
	int client_id;
	struct diag_dci_health_stats health;
	int proc;
};
} __packed;

struct diag_dci_peripherals_t {
	int proc;
	uint16_t list;
} __packed;

/* This is used for querying DCI Log
   or Event Mask */
@@ -138,6 +167,23 @@ struct diag_dci_pkt_header_t {
	int tag;
} __packed;

struct diag_dci_header_t {
	uint8_t start;
	uint8_t version;
	uint16_t length;
	uint8_t cmd_code;
} __packed;

struct dci_ops_tbl_t {
	unsigned char log_mask_composite[DCI_LOG_MASK_SIZE];
	unsigned char event_mask_composite[DCI_EVENT_MASK_SIZE];
	int (*send_log_mask)(int token);
	int (*send_event_mask)(int token);
	uint16_t peripheral_status;
} __packed;

extern struct dci_ops_tbl_t *dci_ops_tbl;

enum {
	DIAG_DCI_NO_ERROR = 1001,	/* No error */
	DIAG_DCI_NO_REG,		/* Could not register */
@@ -156,9 +202,10 @@ struct diag_dci_data_info {
	char time_stamp[DIAG_TS_SIZE];
	uint8_t peripheral;
	uint8_t ch_type;
	uint8_t proc;
};

extern struct diag_dci_data_info *dci_data_smd;
extern struct diag_dci_data_info *dci_traffic;
extern struct mutex dci_stat_mutex;
#endif

@@ -167,42 +214,53 @@ void diag_dci_exit(void);
int diag_dci_register_client(struct diag_dci_reg_tbl_t *reg_entry);
int diag_dci_deinit_client(struct diag_dci_client_tbl *entry);
void diag_update_smd_dci_work_fn(struct work_struct *);
void diag_dci_notify_client(int peripheral_mask, int data);
void diag_dci_notify_client(int peripheral_mask, int data, int proc);
void diag_dci_wakeup_clients(void);
void diag_process_apps_dci_read_data(int data_type, void *buf, int recd_bytes);
int diag_process_smd_dci_read_data(struct diag_smd_info *smd_info, void *buf,
								int recd_bytes);
int diag_process_dci_transaction(unsigned char *buf, int len);
void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source,
			 struct diag_smd_info *smd_info);
			 int token);
void extract_dci_ctrl_pkt(unsigned char *buf, int len, int token);
struct diag_dci_client_tbl *diag_dci_get_client_entry(int client_id);
struct diag_dci_client_tbl *dci_lookup_client_entry_pid(int pid);
int diag_process_hsic_dci_read_data(int index, void *buf, int recd_bytes);
int diag_dci_get_support_list(struct diag_dci_peripherals_t *support_list);
/* DCI Log streaming functions */
void create_dci_log_mask_tbl(unsigned char *tbl_buf);
void update_dci_cumulative_log_mask(int offset, unsigned int byte_index,
						uint8_t byte_mask);
void diag_dci_invalidate_cumulative_log_mask(void);
int diag_send_dci_log_mask(void);
void extract_dci_log(unsigned char *buf, int len, int data_source);
						uint8_t byte_mask, int token);
void diag_dci_invalidate_cumulative_log_mask(int token);
int diag_send_dci_log_mask(int token);
void extract_dci_log(unsigned char *buf, int len, int data_source, int token);
int diag_dci_clear_log_mask(int client_id);
int diag_dci_query_log_mask(struct diag_dci_client_tbl *entry,
			    uint16_t log_code);
/* DCI event streaming functions */
void update_dci_cumulative_event_mask(int offset, uint8_t byte_mask);
void diag_dci_invalidate_cumulative_event_mask(void);
int diag_send_dci_event_mask(void);
void extract_dci_events(unsigned char *buf, int len, int data_source);
void create_dci_event_mask_tbl(unsigned char *tbl_buf);
void update_dci_cumulative_event_mask(int offset, uint8_t byte_mask, int token);
void diag_dci_invalidate_cumulative_event_mask(int token);
int diag_send_dci_event_mask(int token);
void extract_dci_events(unsigned char *buf, int len, int data_source,
			int token);
int diag_dci_clear_event_mask(int client_id);
int diag_dci_query_event_mask(struct diag_dci_client_tbl *entry,
			      uint16_t event_id);
void diag_dci_smd_record_info(int read_bytes, uint8_t ch_type,
			      uint8_t peripheral);
uint8_t diag_dci_get_cumulative_real_time(void);
int diag_dci_set_real_time(int client_id, uint8_t real_time);
void diag_dci_record_traffic(int read_bytes, uint8_t ch_type,
			     uint8_t peripheral, uint8_t proc);
uint8_t diag_dci_get_cumulative_real_time(int token);
int diag_dci_set_real_time(struct diag_dci_client_tbl *entry,
			   uint8_t real_time);
int diag_dci_copy_health_stats(struct diag_dci_health_stats_proc *stats_proc);
/* Functions related to DCI wakeup sources */
void diag_dci_try_activate_wakeup_source(void);
void diag_dci_try_deactivate_wakeup_source(void);
int diag_dci_write_proc(int peripheral, int pkt_type, char *buf, int len);

#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
int diag_send_dci_log_mask_remote(int token);
int diag_send_dci_event_mask_remote(int token);
unsigned char *dci_get_buffer_from_bridge(int index);
int diag_dci_write_bridge(int index, unsigned char *buf, int len);
#endif

#endif
+9 −6
Original line number Diff line number Diff line
@@ -180,7 +180,7 @@ static ssize_t diag_dbgfs_read_status(struct file *file, char __user *ubuf,
		driver->rcvd_feature_mask[LPASS_DATA],
		driver->rcvd_feature_mask[WCNSS_DATA],
		driver->logging_mode,
		driver->real_time_mode);
		driver->real_time_mode[DIAG_LOCAL_PROC]);

#ifdef CONFIG_DIAG_OVER_USB
	ret += scnprintf(buf+ret, buf_size-ret,
@@ -199,7 +199,7 @@ static ssize_t diag_dbgfs_read_dcistats(struct file *file,
	char *buf = NULL;
	unsigned int bytes_remaining, bytes_written = 0;
	unsigned int bytes_in_buf = 0, i = 0;
	struct diag_dci_data_info *temp_data = dci_data_smd;
	struct diag_dci_data_info *temp_data = dci_traffic;
	unsigned int buf_size;
	buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;

@@ -225,7 +225,8 @@ static ssize_t diag_dbgfs_read_dcistats(struct file *file,
			"dci real time vote: %d\n",
			driver->num_dci_client,
			(driver->proc_active_mask & DIAG_PROC_DCI) ? 1 : 0,
			(driver->proc_rt_vote_mask & DIAG_PROC_DCI) ? 1 : 0);
			(driver->proc_rt_vote_mask[DIAG_LOCAL_PROC] &
							DIAG_PROC_DCI) ? 1 : 0);
		bytes_in_buf += bytes_written;
		bytes_remaining -= bytes_written;
#ifdef CONFIG_DIAG_OVER_USB
@@ -254,11 +255,13 @@ static ssize_t diag_dbgfs_read_dcistats(struct file *file,
				"i %-5ld\t"
				"s %-5d\t"
				"p %-5d\t"
				"r %-5d\t"
				"c %-5d\t"
				"t %-15s\n",
				temp_data->iteration,
				temp_data->data_size,
				temp_data->peripheral,
				temp_data->proc,
				temp_data->ch_type,
				temp_data->time_stamp);
			bytes_in_buf += bytes_written;
@@ -708,9 +711,9 @@ void diag_debugfs_init(void)
	diag_dbgfs_dci_finished = 0;

	/* DCI related structures */
	dci_data_smd = kzalloc(sizeof(struct diag_dci_data_info) *
	dci_traffic = kzalloc(sizeof(struct diag_dci_data_info) *
				DIAG_DCI_DEBUG_CNT, GFP_KERNEL);
	if (ZERO_OR_NULL_PTR(dci_data_smd))
	if (ZERO_OR_NULL_PTR(dci_traffic))
		pr_warn("diag: could not allocate memory for dci debug info\n");

	mutex_init(&dci_stat_mutex);
@@ -723,7 +726,7 @@ void diag_debugfs_cleanup(void)
		diag_dbgfs_dent = NULL;
	}

	kfree(dci_data_smd);
	kfree(dci_traffic);
	mutex_destroy(&dci_stat_mutex);
}
#else
+2 −2
Original line number Diff line number Diff line
/* Copyright (c) 2008-2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2008-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -334,7 +334,7 @@ void diag_mask_update_fn(struct work_struct *work)

	if (smd_info->notify_context == SMD_EVENT_OPEN)
		diag_send_diag_mode_update_by_smd(smd_info,
						driver->real_time_mode);
				driver->real_time_mode[DIAG_LOCAL_PROC]);

	smd_info->notify_context = 0;
}
+20 −4
Original line number Diff line number Diff line
@@ -156,7 +156,10 @@
 * processor. This doesn't mean that a peripheral has the
 * feature.
 */
#define NUM_DCI_PROC	(NUM_SMD_DATA_CHANNELS + 1)
#define NUM_DCI_PERIPHERALS	(NUM_SMD_DATA_CHANNELS + 1)

/* Indicates the number of processors that support DCI */
#define NUM_DCI_PROC		2

#define SMD_DATA_TYPE 0
#define SMD_CNTL_TYPE 1
@@ -174,11 +177,19 @@

#define DIAG_TS_SIZE	50


#define MAX_HSIC_DATA_CH	2
#define MAX_HSIC_DCI_CH		2
#define MAX_HSIC_CH		(MAX_HSIC_DATA_CH + MAX_HSIC_DCI_CH)

#define DIAG_LOCAL_PROC	0
#ifdef CONFIG_DIAGFWD_BRIDGE_CODE
/* Local Processor + HSIC channels */
#define DIAG_NUM_PROC	(1 + MAX_HSIC_DATA_CH)
#else
/* Local Processor only */
#define DIAG_NUM_PROC	1
#endif

/* Maximum number of pkt reg supported at initialization*/
extern int diag_max_reg;
extern int diag_threshold_reg;
@@ -256,6 +267,11 @@ struct real_time_vote_t {
	uint8_t real_time_vote;
} __packed;

struct real_time_query_t {
	int real_time;
	int proc;
} __packed;

/* This structure is defined in USB header file */
#ifndef CONFIG_DIAG_OVER_USB
struct diag_request {
@@ -410,10 +426,10 @@ struct diagchar_dev {
	unsigned hdlc_escape;
	int in_busy_pktdata;
	/* Variables for non real time mode */
	int real_time_mode;
	int real_time_mode[DIAG_NUM_PROC];
	int real_time_update_busy;
	uint16_t proc_active_mask;
	uint16_t proc_rt_vote_mask;
	uint16_t proc_rt_vote_mask[DIAG_NUM_PROC];
	struct mutex real_time_mutex;
	struct work_struct diag_real_time_work;
	struct workqueue_struct *diag_real_time_wq;
Loading