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

Commit c2cbb11b authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: hdcp: add response timeout and new messages for sink"

parents bfaad619 327a852b
Loading
Loading
Loading
Loading
+119 −52
Original line number Diff line number Diff line
@@ -65,7 +65,8 @@
#define REPEATER_AUTH_SEND_ACK_MESSAGE_ID      15
#define REPEATER_AUTH_STREAM_MANAGE_MESSAGE_ID 16
#define REPEATER_AUTH_STREAM_READY_MESSAGE_ID  17
#define HDCP2P2_MAX_MESSAGES                   18
#define SKE_SEND_TYPE_ID                       18
#define HDCP2P2_MAX_MESSAGES                   19

#define HDCP1_SET_KEY_MESSAGE_ID       202
#define HDCP1_SET_ENC_MESSAGE_ID       205
@@ -94,7 +95,7 @@
 * minimum wait as per standard is 200 ms. keep it 300 ms
 * to be on safe side.
 */
#define SLEEP_SET_HW_KEY_MS 300
#define SLEEP_SET_HW_KEY_MS 220

#define QSEECOM_ALIGN_SIZE    0x40
#define QSEECOM_ALIGN_MASK    (QSEECOM_ALIGN_SIZE - 1)
@@ -187,6 +188,9 @@ static const struct hdcp_msg_data hdcp_msg_lookup[HDCP2P2_MAX_MESSAGES] = {
	[SKE_SEND_EKS_MESSAGE_ID] = { 2,
		{ {"Edkey_ks", 0x69318, 16}, {"riv", 0x69328, 8} },
		0 },
	[SKE_SEND_TYPE_ID] = { 1,
		{ {"type", 0x69494, 1} },
		0 },
	[REPEATER_AUTH_SEND_RECEIVERID_LIST_MESSAGE_ID] = { 4,
		{ {"RxInfo", 0x69330, 2}, {"seq_num_V", 0x69332, 3},
			{"V'", 0x69335, 16}, {"ridlist", 0x69345, 155} },
@@ -499,8 +503,10 @@ struct hdcp_lib_handle {
	uint32_t tz_ctxhandle;
	uint32_t hdcp_timeout;
	uint32_t timeout_left;
	uint32_t wait_timeout;
	bool no_stored_km_flag;
	bool feature_supported;
	bool authenticated;
	void *client_ctx;
	struct hdcp_client_ops *client_ops;
	struct mutex msg_lock;
@@ -521,7 +527,7 @@ struct hdcp_lib_handle {
	enum hdcp_device_type device_type;

	struct task_struct *thread;
	struct completion topo_wait;
	struct completion poll_wait;

	struct kthread_worker worker;
	struct kthread_work wk_init;
@@ -529,7 +535,7 @@ struct hdcp_lib_handle {
	struct kthread_work wk_msg_recvd;
	struct kthread_work wk_timeout;
	struct kthread_work wk_clean;
	struct kthread_work wk_topology;
	struct kthread_work wk_wait;
	struct kthread_work wk_stream;

	int (*hdcp_app_init)(struct hdcp_lib_handle *handle);
@@ -574,6 +580,7 @@ static const char *hdcp_lib_message_name(int msg_id)
		{15, "REPEATER_AUTH_SEND_ACK"},
		{16, "REPEATER_AUTH_STREAM_MANAGE"},
		{17, "REPEATER_AUTH_STREAM_READY"},
		{18, "SKE_SEND_TYPE_ID"},
	};
	int i;

@@ -612,8 +619,14 @@ static int hdcp_lib_get_next_message(struct hdcp_lib_handle *handle,
	case LC_SEND_L_PRIME_MESSAGE_ID:
		return SKE_SEND_EKS_MESSAGE_ID;
	case SKE_SEND_EKS_MESSAGE_ID:
		if (!handle->repeater_flag)
			return SKE_SEND_TYPE_ID;
	case SKE_SEND_TYPE_ID:
	case REPEATER_AUTH_STREAM_READY_MESSAGE_ID:
	case REPEATER_AUTH_SEND_ACK_MESSAGE_ID:
		if (!handle->repeater_flag)
			return INVALID_MESSAGE_ID;

		if (data->cmd == HDMI_HDCP_WKUP_CMD_SEND_MESSAGE)
			return REPEATER_AUTH_STREAM_MANAGE_MESSAGE_ID;
		else
@@ -628,6 +641,33 @@ static int hdcp_lib_get_next_message(struct hdcp_lib_handle *handle,
	}
}

static void hdcp_lib_wait_for_response(struct hdcp_lib_handle *handle,
				       struct hdmi_hdcp_wakeup_data *data)
{
	switch (handle->last_msg) {
	case AKE_SEND_H_PRIME_MESSAGE_ID:
		if (handle->no_stored_km_flag)
			handle->wait_timeout = HZ;
		else
			handle->wait_timeout = HZ / 4;
		break;
	case AKE_SEND_PAIRING_INFO_MESSAGE_ID:
		handle->wait_timeout = HZ / 4;
		break;
	case REPEATER_AUTH_SEND_RECEIVERID_LIST_MESSAGE_ID:
		if (!handle->authenticated)
			handle->wait_timeout = HZ * 3;
		else
			handle->wait_timeout = 0;
		break;
	default:
		handle->wait_timeout = 0;
	}

	if (handle->wait_timeout)
		queue_kthread_work(&handle->worker, &handle->wk_wait);
}

static void hdcp_lib_wakeup_client(struct hdcp_lib_handle *handle,
				  struct hdmi_hdcp_wakeup_data *data)
{
@@ -639,43 +679,42 @@ static void hdcp_lib_wakeup_client(struct hdcp_lib_handle *handle,

	data->abort_mask = REAUTH_REQ | LINK_INTEGRITY_FAILURE;

	if (data->cmd == HDMI_HDCP_WKUP_CMD_SEND_MESSAGE ||
	    data->cmd == HDMI_HDCP_WKUP_CMD_RECV_MESSAGE ||
	    data->cmd == HDMI_HDCP_WKUP_CMD_LINK_POLL) {
	if (data->cmd == HDMI_HDCP_WKUP_CMD_RECV_MESSAGE ||
	    data->cmd == HDMI_HDCP_WKUP_CMD_LINK_POLL)
		handle->last_msg = hdcp_lib_get_next_message(handle, data);

	if (handle->last_msg != INVALID_MESSAGE_ID &&
	    data->cmd != HDMI_HDCP_WKUP_CMD_STATUS_SUCCESS &&
	    data->cmd != HDMI_HDCP_WKUP_CMD_STATUS_FAILED) {
		u32 msg_num, rx_status;
		const struct hdcp_msg_part *msg;

		pr_debug("lib->client: %s (%s)\n",
			hdmi_hdcp_cmd_to_str(data->cmd),
			hdcp_lib_message_name(handle->last_msg));

		if (handle->last_msg > INVALID_MESSAGE_ID &&
		    handle->last_msg < HDCP2P2_MAX_MESSAGES) {
			u32 msg_num, rx_status;
			const struct hdcp_msg_part *msg;

		data->message_data = &hdcp_msg_lookup[handle->last_msg];

		msg_num = data->message_data->num_messages;
		msg = data->message_data->messages;
		rx_status = data->message_data->rx_status;

			pr_debug("rxstatus 0x%x\n", rx_status);
		pr_debug("%10s | %6s | %4s\n", "name", "offset", "len");

		for (i = 0; i < msg_num; i++)
			pr_debug("%10s | %6x | %4d\n",
				msg[i].name, msg[i].offset,
				msg[i].length);
		}
	} else {
		pr_debug("lib->client: %s\n",
			hdmi_hdcp_cmd_to_str(data->cmd));
		pr_debug("lib->client: %s\n", hdmi_hdcp_cmd_to_str(data->cmd));
	}

	rc = handle->client_ops->wakeup(data);
	if (rc)
		pr_err("error sending %s to client\n",
		       hdmi_hdcp_cmd_to_str(data->cmd));

	hdcp_lib_wait_for_response(handle, data);
}

static inline void hdcp_lib_send_message(struct hdcp_lib_handle *handle)
@@ -1286,6 +1325,8 @@ static int hdcp_lib_txmtr_init_legacy(struct hdcp_lib_handle *handle)
		 hdcp_lib_message_name((int)rsp_buf->message[0]),
		 jiffies_to_msecs(jiffies));

	handle->last_msg = (int)rsp_buf->message[0];

	/* send the response to HDMI driver */
	memset(handle->listener_buf, 0, MAX_TX_MESSAGE_SIZE);
	memcpy(handle->listener_buf, (unsigned char *)rsp_buf->message,
@@ -1404,6 +1445,8 @@ static int hdcp_lib_start_auth(struct hdcp_lib_handle *handle)
		 hdcp_lib_message_name((int)rsp_buf->message[0]),
		 jiffies_to_msecs(jiffies));

	handle->last_msg = (int)rsp_buf->message[0];

	/* send the response to HDMI driver */
	memset(handle->listener_buf, 0, MAX_TX_MESSAGE_SIZE);
	memcpy(handle->listener_buf, (unsigned char *)rsp_buf->message,
@@ -1470,6 +1513,8 @@ static void hdcp_lib_stream(struct hdcp_lib_handle *handle)
	pr_debug("message received from TZ: %s\n",
		 hdcp_lib_message_name((int)rsp_buf->msg[0]));

	handle->last_msg = (int)rsp_buf->msg[0];

	memset(handle->listener_buf, 0, MAX_TX_MESSAGE_SIZE);
	memcpy(handle->listener_buf, (unsigned char *)rsp_buf->msg,
	       rsp_buf->msglen);
@@ -1550,11 +1595,11 @@ static void hdcp_lib_check_worker_status(struct hdcp_lib_handle *handle)
	if (handle->worker.current_work == &handle->wk_clean)
		pr_debug("clean work executing\n");

	if (!list_empty(&handle->wk_topology.node))
		pr_debug("topology work queued\n");
	if (!list_empty(&handle->wk_wait.node))
		pr_debug("wait work queued\n");

	if (handle->worker.current_work == &handle->wk_topology)
		pr_debug("topology work executing\n");
	if (handle->worker.current_work == &handle->wk_wait)
		pr_debug("wait work executing\n");

	if (!list_empty(&handle->wk_stream.node))
		pr_debug("stream work queued\n");
@@ -1613,7 +1658,7 @@ static void hdcp_lib_update_exec_type(void *ctx, bool tethered)
	mutex_unlock(&handle->wakeup_mutex);
}

static int hdcp_lib_wakeup(struct hdcp_lib_wakeup_data *data)
static int hdcp_lib_wakeup_thread(struct hdcp_lib_wakeup_data *data)
{
	struct hdcp_lib_handle *handle;
	int rc = 0;
@@ -1630,8 +1675,9 @@ static int hdcp_lib_wakeup(struct hdcp_lib_wakeup_data *data)
	handle->wakeup_cmd = data->cmd;
	handle->timeout_left = data->timeout;

	pr_debug("client->lib: %s\n",
		 hdcp_lib_cmd_to_str(handle->wakeup_cmd));
	pr_debug("client->lib: %s (%s)\n",
		hdcp_lib_cmd_to_str(data->cmd),
		hdcp_lib_message_name(handle->last_msg));

	rc = hdcp_lib_check_valid_state(handle);
	if (rc)
@@ -1655,8 +1701,8 @@ static int hdcp_lib_wakeup(struct hdcp_lib_wakeup_data *data)
	}
	mutex_unlock(&handle->msg_lock);

	if (!completion_done(&handle->topo_wait))
		complete_all(&handle->topo_wait);
	if (!completion_done(&handle->poll_wait))
		complete_all(&handle->poll_wait);

	switch (handle->wakeup_cmd) {
	case HDCP_LIB_WKUP_CMD_START:
@@ -1719,22 +1765,30 @@ static void hdcp_lib_msg_sent(struct hdcp_lib_handle *handle)
	cdata.context = handle->client_ctx;

	switch (handle->last_msg_sent) {
	case SKE_SEND_EKS_MESSAGE_ID:
		if (handle->repeater_flag) {
			if (!atomic_read(&handle->hdcp_off))
				queue_kthread_work(&handle->worker,
						   &handle->wk_topology);
		}

	case SKE_SEND_TYPE_ID:
		if (!hdcp_lib_enable_encryption(handle)) {
			handle->authenticated = true;

			cdata.cmd = HDMI_HDCP_WKUP_CMD_STATUS_SUCCESS;
			hdcp_lib_wakeup_client(handle, &cdata);
		}

		/* poll for link check */
		cdata.cmd = HDMI_HDCP_WKUP_CMD_LINK_POLL;
		break;
	case SKE_SEND_EKS_MESSAGE_ID:
		if (handle->repeater_flag) {
			/* poll for link check */
			cdata.cmd = HDMI_HDCP_WKUP_CMD_LINK_POLL;
		} else {
			if (!atomic_read(&handle->hdcp_off))
				HDCP_LIB_EXECUTE(clean);
			memset(handle->listener_buf, 0, MAX_TX_MESSAGE_SIZE);
			handle->listener_buf[0] = SKE_SEND_TYPE_ID;
			handle->msglen = 2;
			cdata.cmd = HDMI_HDCP_WKUP_CMD_SEND_MESSAGE;
			cdata.send_msg_buf = handle->listener_buf;
			cdata.send_msg_len = handle->msglen;
			handle->last_msg = hdcp_lib_get_next_message(handle,
						&cdata);
		}
		break;
	case REPEATER_AUTH_SEND_ACK_MESSAGE_ID:
@@ -1915,6 +1969,8 @@ static void hdcp_lib_clean(struct hdcp_lib_handle *handle)
		return;
	}

	handle->authenticated = false;

	hdcp_lib_txmtr_deinit(handle);
	if (!handle->legacy_app)
		hdcp_lib_session_deinit(handle);
@@ -2040,6 +2096,13 @@ static void hdcp_lib_msg_recvd(struct hdcp_lib_handle *handle)
	    (rc == 0) && (rsp_buf->status == 0)) {
		pr_debug("Got Auth_Stream_Ready, nothing sent to rx\n");

		if (!hdcp_lib_enable_encryption(handle)) {
			handle->authenticated = true;

			cdata.cmd = HDMI_HDCP_WKUP_CMD_STATUS_SUCCESS;
			hdcp_lib_wakeup_client(handle, &cdata);
		}

		cdata.cmd = HDMI_HDCP_WKUP_CMD_LINK_POLL;
		goto exit;
	}
@@ -2057,6 +2120,8 @@ static void hdcp_lib_msg_recvd(struct hdcp_lib_handle *handle)
		 hdcp_lib_message_name((int)rsp_buf->msg[0]),
		 jiffies_to_msecs(jiffies));

	handle->last_msg = (int)rsp_buf->msg[0];

	/* set the flag if response is AKE_No_Stored_km */
	if (((int)rsp_buf->msg[0] == AKE_NO_STORED_KM_MESSAGE_ID)) {
		pr_debug("Setting no_stored_km_flag\n");
@@ -2101,12 +2166,11 @@ static void hdcp_lib_msg_recvd_work(struct kthread_work *work)
	hdcp_lib_msg_recvd(handle);
}

static void hdcp_lib_topology_work(struct kthread_work *work)
static void hdcp_lib_wait_work(struct kthread_work *work)
{
	u32 timeout;
	struct hdcp_lib_handle *handle = container_of(work,
						      struct hdcp_lib_handle,
						      wk_topology);
				struct hdcp_lib_handle, wk_wait);

	if (!handle) {
		pr_err("invalid input\n");
@@ -2123,14 +2187,17 @@ static void hdcp_lib_topology_work(struct kthread_work *work)
		return;
	}

	reinit_completion(&handle->topo_wait);
	timeout = wait_for_completion_timeout(&handle->topo_wait, HZ * 3);
	reinit_completion(&handle->poll_wait);
	timeout = wait_for_completion_timeout(&handle->poll_wait,
			handle->wait_timeout);
	if (!timeout) {
		pr_err("topology receiver id list timeout\n");
		pr_err("wait timeout\n");

		if (!atomic_read(&handle->hdcp_off))
			HDCP_LIB_EXECUTE(clean);
	}

	handle->wait_timeout = 0;
}

bool hdcp1_check_if_supported_load_app(void)
@@ -2266,7 +2333,7 @@ int hdcp_library_register(struct hdcp_register_data *data)

	/* populate ops to be called by client */
	data->txmtr_ops->feature_supported = hdcp_lib_client_feature_supported;
	data->txmtr_ops->wakeup = hdcp_lib_wakeup;
	data->txmtr_ops->wakeup = hdcp_lib_wakeup_thread;
	data->txmtr_ops->update_exec_type = hdcp_lib_update_exec_type;

	handle = kzalloc(sizeof(*handle), GFP_KERNEL);
@@ -2296,10 +2363,10 @@ int hdcp_library_register(struct hdcp_register_data *data)
	init_kthread_work(&handle->wk_msg_recvd, hdcp_lib_msg_recvd_work);
	init_kthread_work(&handle->wk_timeout, hdcp_lib_manage_timeout_work);
	init_kthread_work(&handle->wk_clean, hdcp_lib_cleanup_work);
	init_kthread_work(&handle->wk_topology, hdcp_lib_topology_work);
	init_kthread_work(&handle->wk_wait, hdcp_lib_wait_work);
	init_kthread_work(&handle->wk_stream, hdcp_lib_query_stream_work);

	init_completion(&handle->topo_wait);
	init_completion(&handle->poll_wait);

	handle->listener_buf = kzalloc(MAX_TX_MESSAGE_SIZE, GFP_KERNEL);
	if (!(handle->listener_buf)) {