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

Commit 571cf424 authored by Manoj Prabhu B's avatar Manoj Prabhu B
Browse files

diag: Add support for header untagging



This patch provides the support to segregate different PD data
received on DATA channel onto separate buffers and then onto
its own data stream based on received diag private id header
in the peripheral data packet header.
This patch adds a new feature mask supporting the feature and
a new IOCTL querying the support of the feature.

CRs-Fixed: 1112307
Change-Id: Id76e718f83e09defc221f9ee169d4676d8e57d8a
Signed-off-by: default avatarManoj Prabhu B <bmanoj@codeaurora.org>
parent 7843ac5a
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@ static ssize_t diag_dbgfs_read_status(struct file *file, char __user *ubuf,
		"Uses Device Tree: %d\n"
		"Apps Supports Separate CMDRSP: %d\n"
		"Apps Supports HDLC Encoding: %d\n"
		"Apps Supports Header Untagging: %d\n"
		"Apps Supports Sockets: %d\n"
		"Logging Mode: %d\n"
		"RSP Buffer is Busy: %d\n"
@@ -83,6 +84,7 @@ static ssize_t diag_dbgfs_read_status(struct file *file, char __user *ubuf,
		driver->use_device_tree,
		driver->supports_separate_cmdrsp,
		driver->supports_apps_hdlc_encoding,
		driver->supports_apps_header_untagging,
		driver->supports_sockets,
		driver->logging_mode,
		driver->rsp_buf_busy,
@@ -94,7 +96,7 @@ static ssize_t diag_dbgfs_read_status(struct file *file, char __user *ubuf,

	for (i = 0; i < NUM_PERIPHERALS; i++) {
		ret += scnprintf(buf+ret, buf_size-ret,
			"p: %s Feature: %02x %02x |%c%c%c%c%c%c%c%c|\n",
			"p: %s Feature: %02x %02x |%c%c%c%c%c%c%c%c%c|\n",
			PERIPHERAL_STRING(i),
			driver->feature[i].feature_mask[0],
			driver->feature[i].feature_mask[1],
@@ -105,7 +107,8 @@ static ssize_t diag_dbgfs_read_status(struct file *file, char __user *ubuf,
			driver->feature[i].mask_centralization ? 'M':'m',
			driver->feature[i].stm_support ? 'Q':'q',
			driver->feature[i].sockets_enabled ? 'S':'s',
			driver->feature[i].sent_feature_mask ? 'T':'t');
			driver->feature[i].sent_feature_mask ? 'T':'t',
			driver->feature[i].untag_header ? 'U':'u');
	}

#ifdef CONFIG_DIAG_OVER_USB
+89 −29
Original line number Diff line number Diff line
@@ -28,7 +28,8 @@
#define DIAG_SET_FEATURE_MASK(x) (feature_bytes[(x)/8] |= (1 << (x & 0x7)))

#define diag_check_update(x)	\
	(!info || (info && (info->peripheral_mask & MD_PERIPHERAL_MASK(x)))) \
	(!info || (info && (info->peripheral_mask & MD_PERIPHERAL_MASK(x))) \
	|| (info && (info->peripheral_mask & MD_PERIPHERAL_PD_MASK(x)))) \

struct diag_mask_info msg_mask;
struct diag_mask_info msg_bt_mask;
@@ -90,8 +91,8 @@ static void diag_send_log_mask_update(uint8_t peripheral, int equip_id)
	int err = 0;
	int send_once = 0;
	int header_len = sizeof(struct diag_ctrl_log_mask);
	uint8_t *buf = NULL;
	uint8_t *temp = NULL;
	uint8_t *buf = NULL, *temp = NULL;
	uint8_t upd = 0;
	uint32_t mask_size = 0;
	struct diag_ctrl_log_mask ctrl_pkt;
	struct diag_mask_info *mask_info = NULL;
@@ -107,11 +108,25 @@ static void diag_send_log_mask_update(uint8_t peripheral, int equip_id)
		return;
	}

	if (driver->md_session_mask != 0 &&
	    driver->md_session_mask & MD_PERIPHERAL_MASK(peripheral))
		mask_info = driver->md_session_map[peripheral]->log_mask;
	else
	if (driver->md_session_mask != 0) {
		if (driver->md_session_mask & MD_PERIPHERAL_MASK(peripheral)) {
			if (driver->md_session_map[peripheral])
				mask_info =
				driver->md_session_map[peripheral]->log_mask;
		} else if (driver->md_session_mask &
				MD_PERIPHERAL_PD_MASK(peripheral)) {
			upd = diag_mask_to_pd_value(driver->md_session_mask);
			if (upd && driver->md_session_map[upd])
				mask_info =
				driver->md_session_map[upd]->log_mask;
		} else {
			DIAG_LOG(DIAG_DEBUG_MASKS,
			"asking for mask update with unknown session mask\n");
			return;
		}
	} else {
		mask_info = &log_mask;
	}

	if (!mask_info || !mask_info->ptr || !mask_info->update_buf)
		return;
@@ -196,8 +211,8 @@ static void diag_send_log_mask_update(uint8_t peripheral, int equip_id)

static void diag_send_event_mask_update(uint8_t peripheral)
{
	uint8_t *buf = NULL;
	uint8_t *temp = NULL;
	uint8_t *buf = NULL, *temp = NULL;
	uint8_t upd = 0;
	struct diag_ctrl_event_mask header;
	struct diag_mask_info *mask_info = NULL;
	int num_bytes = EVENT_COUNT_TO_BYTES(driver->last_event_id);
@@ -221,11 +236,25 @@ static void diag_send_event_mask_update(uint8_t peripheral)
		return;
	}

	if (driver->md_session_mask != 0 &&
	    (driver->md_session_mask & MD_PERIPHERAL_MASK(peripheral)))
		mask_info = driver->md_session_map[peripheral]->event_mask;
	else
	if (driver->md_session_mask != 0) {
		if (driver->md_session_mask & MD_PERIPHERAL_MASK(peripheral)) {
			if (driver->md_session_map[peripheral])
				mask_info =
				driver->md_session_map[peripheral]->event_mask;
		} else if (driver->md_session_mask &
				MD_PERIPHERAL_PD_MASK(peripheral)) {
			upd = diag_mask_to_pd_value(driver->md_session_mask);
			if (upd && driver->md_session_map[upd])
				mask_info =
				driver->md_session_map[upd]->event_mask;
		} else {
			DIAG_LOG(DIAG_DEBUG_MASKS,
			"asking for mask update with unknown session mask\n");
			return;
		}
	} else {
		mask_info = &event_mask;
	}

	if (!mask_info || !mask_info->ptr || !mask_info->update_buf)
		return;
@@ -285,8 +314,8 @@ static void diag_send_msg_mask_update(uint8_t peripheral, int first, int last)
	int err = 0;
	int header_len = sizeof(struct diag_ctrl_msg_mask);
	int temp_len = 0;
	uint8_t *buf = NULL;
	uint8_t *temp = NULL;
	uint8_t *buf = NULL, *temp = NULL;
	uint8_t upd = 0;
	uint32_t mask_size = 0;
	struct diag_mask_info *mask_info = NULL;
	struct diag_msg_mask_t *mask = NULL;
@@ -303,11 +332,25 @@ static void diag_send_msg_mask_update(uint8_t peripheral, int first, int last)
		return;
	}

	if (driver->md_session_mask != 0 &&
	    (driver->md_session_mask & MD_PERIPHERAL_MASK(peripheral)))
		mask_info = driver->md_session_map[peripheral]->msg_mask;
	else
	if (driver->md_session_mask != 0) {
		if (driver->md_session_mask & MD_PERIPHERAL_MASK(peripheral)) {
			if (driver->md_session_map[peripheral])
				mask_info =
				driver->md_session_map[peripheral]->msg_mask;
		} else if (driver->md_session_mask &
				MD_PERIPHERAL_PD_MASK(peripheral)) {
			upd = diag_mask_to_pd_value(driver->md_session_mask);
			if (upd && driver->md_session_map[upd])
				mask_info =
				driver->md_session_map[upd]->msg_mask;
		} else {
			DIAG_LOG(DIAG_DEBUG_MASKS,
			"asking for mask update with unknown session mask\n");
			return;
		}
	} else {
		mask_info = &msg_mask;
	}

	if (!mask_info || !mask_info->ptr || !mask_info->update_buf)
		return;
@@ -466,6 +509,13 @@ static void diag_send_feature_mask_update(uint8_t peripheral)
		DIAG_SET_FEATURE_MASK(F_DIAG_REQ_RSP_SUPPORT);
	if (driver->supports_apps_hdlc_encoding)
		DIAG_SET_FEATURE_MASK(F_DIAG_APPS_HDLC_ENCODE);
	if (driver->supports_apps_header_untagging) {
		if (peripheral == PERIPHERAL_MODEM) {
			DIAG_SET_FEATURE_MASK(F_DIAG_PKT_HEADER_UNTAG);
			driver->peripheral_untag[peripheral] =
				ENABLE_PKT_HEADER_UNTAGGING;
		}
	}
	DIAG_SET_FEATURE_MASK(F_DIAG_MASK_CENTRALIZATION);
	if (driver->supports_sockets)
		DIAG_SET_FEATURE_MASK(F_DIAG_SOCKETS_ENABLED);
@@ -1933,6 +1983,15 @@ int diag_copy_to_user_log_mask(char __user *buf, size_t count,
void diag_send_updates_peripheral(uint8_t peripheral)
{
	diag_send_feature_mask_update(peripheral);
	/*
	 * Masks (F3, logs and events) will be sent to
	 * peripheral immediately following feature mask update only
	 * if diag_id support is not present or
	 * diag_id support is present and diag_id has been sent to
	 * peripheral.
	 */
	if (!driver->feature[peripheral].diag_id_support ||
		driver->diag_id_sent[peripheral]) {
		if (driver->time_sync_enabled)
			diag_send_time_sync_update(peripheral);
		mutex_lock(&driver->md_session_lock);
@@ -1945,6 +2004,7 @@ void diag_send_updates_peripheral(uint8_t peripheral)
		diag_send_peripheral_buffering_mode(
					&driver->buffering_mode[peripheral]);
	}
}

int diag_process_apps_masks(unsigned char *buf, int len,
			    struct diag_md_session_t *info)
+23 −11
Original line number Diff line number Diff line
/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2017, 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
@@ -29,6 +29,7 @@
#include "diagmem.h"
#include "diagfwd.h"
#include "diagfwd_peripheral.h"
#include "diag_ipc_logging.h"

struct diag_md_info diag_md[NUM_DIAG_MD_DEV] = {
	{
@@ -132,7 +133,7 @@ int diag_md_write(int id, unsigned char *buf, int len, int ctx)
	uint8_t found = 0;
	unsigned long flags;
	struct diag_md_info *ch = NULL;
	uint8_t peripheral;
	int peripheral;
	struct diag_md_session_t *session_info = NULL;

	if (id < 0 || id >= NUM_DIAG_MD_DEV || id >= DIAG_NUM_PROC)
@@ -141,11 +142,12 @@ int diag_md_write(int id, unsigned char *buf, int len, int ctx)
	if (!buf || len < 0)
		return -EINVAL;

	peripheral = GET_BUF_PERIPHERAL(ctx);
	if (peripheral > NUM_PERIPHERALS)
	peripheral = diag_md_get_peripheral(ctx);
	if (peripheral < 0)
		return -EINVAL;

	session_info = diag_md_session_get_peripheral(peripheral);
	session_info =
		diag_md_session_get_peripheral(peripheral);
	if (!session_info)
		return -EIO;

@@ -214,7 +216,7 @@ int diag_md_copy_to_user(char __user *buf, int *pret, size_t buf_size,
	struct diag_md_info *ch = NULL;
	struct diag_buf_tbl_t *entry = NULL;
	uint8_t drain_again = 0;
	uint8_t peripheral = 0;
	int peripheral = 0;
	struct diag_md_session_t *session_info = NULL;

	for (i = 0; i < NUM_DIAG_MD_DEV && !err; i++) {
@@ -223,12 +225,15 @@ int diag_md_copy_to_user(char __user *buf, int *pret, size_t buf_size,
			entry = &ch->tbl[j];
			if (entry->len <= 0)
				continue;
			peripheral = GET_BUF_PERIPHERAL(entry->ctx);
			/* Account for Apps data as well */
			if (peripheral > NUM_PERIPHERALS)

			peripheral = diag_md_get_peripheral(entry->ctx);
			if (peripheral < 0)
				goto drop_data;
			session_info =
			diag_md_session_get_peripheral(peripheral);
			if (!session_info)
				goto drop_data;

			if (session_info && info &&
				(session_info->pid != info->pid))
				continue;
@@ -320,8 +325,15 @@ int diag_md_close_peripheral(int id, uint8_t peripheral)
	spin_lock_irqsave(&ch->lock, flags);
	for (i = 0; i < ch->num_tbl_entries && !found; i++) {
		entry = &ch->tbl[i];
		if (GET_BUF_PERIPHERAL(entry->ctx) != peripheral)

		if (peripheral > NUM_PERIPHERALS) {
			if (GET_PD_CTXT(entry->ctx) != peripheral)
				continue;
		} else {
			if (GET_BUF_PERIPHERAL(entry->ctx) !=
					peripheral)
				continue;
		}
		found = 1;
		if (ch->ops && ch->ops->write_done) {
			ch->ops->write_done(entry->buf, entry->len,
+18 −7
Original line number Diff line number Diff line
/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2017, 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
@@ -27,7 +27,8 @@
#include "diag_mux.h"
#include "diag_usb.h"
#include "diag_memorydevice.h"

#include "diagfwd_peripheral.h"
#include "diag_ipc_logging.h"

struct diag_mux_state_t *diag_mux;
static struct diag_logger_t usb_logger;
@@ -141,9 +142,13 @@ int diag_mux_write(int proc, unsigned char *buf, int len, int ctx)
	if (!diag_mux)
		return -EIO;

	peripheral = GET_BUF_PERIPHERAL(ctx);
	if (peripheral > NUM_PERIPHERALS)
	peripheral = diag_md_get_peripheral(ctx);
	if (peripheral < 0) {
		DIAG_LOG(DIAG_DEBUG_PERIPHERALS,
			"diag:%s:%d invalid peripheral = %d\n",
			__func__, __LINE__, peripheral);
		return -EINVAL;
	}

	if (MD_PERIPHERAL_MASK(peripheral) & diag_mux->mux_mask)
		logger = diag_mux->md_ptr;
@@ -162,8 +167,13 @@ int diag_mux_close_peripheral(int proc, uint8_t peripheral)
	if (proc < 0 || proc >= NUM_MUX_PROC)
		return -EINVAL;
	/* Peripheral should account for Apps data as well */
	if (peripheral > NUM_PERIPHERALS)
	if (peripheral > NUM_PERIPHERALS) {
		if (!driver->num_pd_session)
			return -EINVAL;
		if (peripheral > NUM_MD_SESSIONS)
			return -EINVAL;
	}

	if (!diag_mux)
		return -EIO;

@@ -184,7 +194,8 @@ int diag_mux_switch_logging(int *req_mode, int *peripheral_mask)
	if (!req_mode)
		return -EINVAL;

	if (*peripheral_mask <= 0 || *peripheral_mask > DIAG_CON_ALL) {
	if (*peripheral_mask <= 0 ||
		(*peripheral_mask > (DIAG_CON_ALL | DIAG_CON_UPD_ALL))) {
		pr_err("diag: mask %d in %s\n", *peripheral_mask, __func__);
		return -EINVAL;
	}
+25 −4
Original line number Diff line number Diff line
@@ -58,19 +58,23 @@
#define DIAG_CTRL_MSG_F3_MASK	11
#define CONTROL_CHAR	0x7E

#define DIAG_ID_ROOT_STRING "root"

#define DIAG_CON_APSS		(0x0001)	/* Bit mask for APSS */
#define DIAG_CON_MPSS		(0x0002)	/* Bit mask for MPSS */
#define DIAG_CON_LPASS		(0x0004)	/* Bit mask for LPASS */
#define DIAG_CON_WCNSS		(0x0008)	/* Bit mask for WCNSS */
#define DIAG_CON_SENSORS	(0x0010)	/* Bit mask for Sensors */
#define DIAG_CON_WDSP		(0x0020)	/* Bit mask for WDSP */
#define DIAG_CON_CDSP (0x0040)
#define DIAG_CON_CDSP		(0x0040)	/* Bit mask for CDSP */

#define DIAG_CON_UPD_WLAN		(0x1000) /*Bit mask for WLAN PD*/
#define DIAG_CON_NONE		(0x0000)	/* Bit mask for No SS*/
#define DIAG_CON_ALL		(DIAG_CON_APSS | DIAG_CON_MPSS \
				| DIAG_CON_LPASS | DIAG_CON_WCNSS \
				| DIAG_CON_SENSORS | DIAG_CON_WDSP \
				| DIAG_CON_CDSP)
#define DIAG_CON_UPD_ALL	(DIAG_CON_UPD_WLAN)

#define DIAG_STM_MODEM	0x01
#define DIAG_STM_LPASS	0x02
@@ -165,7 +169,7 @@
#define PKT_ALLOC	1
#define PKT_RESET	2

#define FEATURE_MASK_LEN	2
#define FEATURE_MASK_LEN	4

#define DIAG_MD_NONE			0
#define DIAG_MD_PERIPHERAL		1
@@ -209,11 +213,18 @@
#define NUM_PERIPHERALS		6
#define APPS_DATA		(NUM_PERIPHERALS)

#define UPD_WLAN		7
#define NUM_UPD			1
#define MAX_PERIPHERAL_UPD			1
/* Number of sessions possible in Memory Device Mode. +1 for Apps data */
#define NUM_MD_SESSIONS		(NUM_PERIPHERALS + 1)
#define NUM_MD_SESSIONS		(NUM_PERIPHERALS \
					+ NUM_UPD + 1)

#define MD_PERIPHERAL_MASK(x)	(1 << x)

#define MD_PERIPHERAL_PD_MASK(x)					\
	((x == PERIPHERAL_MODEM) ? (1 << UPD_WLAN) : 0)\

/*
 * Number of stm processors includes all the peripherals and
 * apps.Added 1 below to indicate apps
@@ -439,6 +450,7 @@ struct diag_partial_pkt_t {
struct diag_logging_mode_param_t {
	uint32_t req_mode;
	uint32_t peripheral_mask;
	uint32_t pd_mask;
	uint8_t mode_param;
} __packed;

@@ -485,11 +497,13 @@ struct diag_feature_t {
	uint8_t log_on_demand;
	uint8_t separate_cmd_rsp;
	uint8_t encode_hdlc;
	uint8_t untag_header;
	uint8_t peripheral_buffering;
	uint8_t mask_centralization;
	uint8_t stm_support;
	uint8_t sockets_enabled;
	uint8_t sent_feature_mask;
	uint8_t diag_id_support;
};

struct diagchar_dev {
@@ -516,6 +530,8 @@ struct diagchar_dev {
	int use_device_tree;
	int supports_separate_cmdrsp;
	int supports_apps_hdlc_encoding;
	int supports_apps_header_untagging;
	int peripheral_untag[NUM_PERIPHERALS];
	int supports_sockets;
	/* The state requested in the STM command */
	int stm_state_requested[NUM_STM_PROCESSORS];
@@ -612,6 +628,10 @@ struct diagchar_dev {
	int in_busy_dcipktdata;
	int logging_mode;
	int logging_mask;
	int pd_logging_mode[NUM_UPD];
	int pd_session_clear[NUM_UPD];
	int num_pd_session;
	int diag_id_sent[NUM_PERIPHERALS];
	int mask_check;
	uint32_t md_session_mask;
	uint8_t md_session_mode;
@@ -672,6 +692,7 @@ void diag_cmd_remove_reg_by_proc(int proc);
int diag_cmd_chk_polling(struct diag_cmd_reg_entry_t *entry);
int diag_mask_param(void);
void diag_clear_masks(struct diag_md_session_t *info);
uint8_t diag_mask_to_pd_value(uint32_t peripheral_mask);

void diag_record_stats(int type, int flag);

Loading