/*
 * Copyright 2018 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: AMD
 *
 */

#include <linux/delay.h>

#include "hdcp.h"

static inline enum mod_hdcp_status check_receiver_id_list_ready(struct mod_hdcp *hdcp)
{
	uint8_t is_ready = 0;

	if (is_dp_hdcp(hdcp))
		is_ready = HDCP_2_2_DP_RXSTATUS_READY(hdcp->auth.msg.hdcp2.rxstatus_dp) ? 1 : 0;
	else
		is_ready = (HDCP_2_2_HDMI_RXSTATUS_READY(hdcp->auth.msg.hdcp2.rxstatus[1]) &&
				(HDCP_2_2_HDMI_RXSTATUS_MSG_SZ_HI(hdcp->auth.msg.hdcp2.rxstatus[1]) << 8 |
						hdcp->auth.msg.hdcp2.rxstatus[0])) ? 1 : 0;
	return is_ready ? MOD_HDCP_STATUS_SUCCESS :
			MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_NOT_READY;
}

static inline enum mod_hdcp_status check_hdcp2_capable(struct mod_hdcp *hdcp)
{
	enum mod_hdcp_status status;

	if (is_dp_hdcp(hdcp))
		status = (hdcp->auth.msg.hdcp2.rxcaps_dp[0] == HDCP_2_2_RX_CAPS_VERSION_VAL) &&
				HDCP_2_2_DP_HDCP_CAPABLE(hdcp->auth.msg.hdcp2.rxcaps_dp[2]) ?
				MOD_HDCP_STATUS_SUCCESS :
				MOD_HDCP_STATUS_HDCP2_NOT_CAPABLE;
	else
		status = (hdcp->auth.msg.hdcp2.hdcp2version_hdmi & HDCP_2_2_HDMI_SUPPORT_MASK) ?
				MOD_HDCP_STATUS_SUCCESS :
				MOD_HDCP_STATUS_HDCP2_NOT_CAPABLE;
	return status;
}

static inline enum mod_hdcp_status check_reauthentication_request(
		struct mod_hdcp *hdcp)
{
	uint8_t ret = 0;

	if (is_dp_hdcp(hdcp))
		ret = HDCP_2_2_DP_RXSTATUS_REAUTH_REQ(hdcp->auth.msg.hdcp2.rxstatus_dp) ?
				MOD_HDCP_STATUS_HDCP2_REAUTH_REQUEST :
				MOD_HDCP_STATUS_SUCCESS;
	else
		ret = HDCP_2_2_HDMI_RXSTATUS_REAUTH_REQ(hdcp->auth.msg.hdcp2.rxstatus[1]) ?
				MOD_HDCP_STATUS_HDCP2_REAUTH_REQUEST :
				MOD_HDCP_STATUS_SUCCESS;
	return ret;
}

static inline enum mod_hdcp_status check_link_integrity_failure_dp(
		struct mod_hdcp *hdcp)
{
	return HDCP_2_2_DP_RXSTATUS_LINK_FAILED(hdcp->auth.msg.hdcp2.rxstatus_dp) ?
			MOD_HDCP_STATUS_HDCP2_REAUTH_LINK_INTEGRITY_FAILURE :
			MOD_HDCP_STATUS_SUCCESS;
}

static enum mod_hdcp_status check_ake_cert_available(struct mod_hdcp *hdcp)
{
	enum mod_hdcp_status status;
	uint16_t size;

	if (is_dp_hdcp(hdcp)) {
		status = MOD_HDCP_STATUS_SUCCESS;
	} else {
		status = mod_hdcp_read_rxstatus(hdcp);
		if (status == MOD_HDCP_STATUS_SUCCESS) {
			size = HDCP_2_2_HDMI_RXSTATUS_MSG_SZ_HI(hdcp->auth.msg.hdcp2.rxstatus[1]) << 8 |
			       hdcp->auth.msg.hdcp2.rxstatus[0];
			status = (size == sizeof(hdcp->auth.msg.hdcp2.ake_cert)) ?
					MOD_HDCP_STATUS_SUCCESS :
					MOD_HDCP_STATUS_HDCP2_AKE_CERT_PENDING;
		}
	}
	return status;
}

static enum mod_hdcp_status check_h_prime_available(struct mod_hdcp *hdcp)
{
	enum mod_hdcp_status status;
	uint8_t size;

	status = mod_hdcp_read_rxstatus(hdcp);
	if (status != MOD_HDCP_STATUS_SUCCESS)
		goto out;

	if (is_dp_hdcp(hdcp)) {
		status = HDCP_2_2_DP_RXSTATUS_H_PRIME(hdcp->auth.msg.hdcp2.rxstatus_dp) ?
				MOD_HDCP_STATUS_SUCCESS :
				MOD_HDCP_STATUS_HDCP2_H_PRIME_PENDING;
	} else {
		size = HDCP_2_2_HDMI_RXSTATUS_MSG_SZ_HI(hdcp->auth.msg.hdcp2.rxstatus[1]) << 8 |
		       hdcp->auth.msg.hdcp2.rxstatus[0];
		status = (size == sizeof(hdcp->auth.msg.hdcp2.ake_h_prime)) ?
				MOD_HDCP_STATUS_SUCCESS :
				MOD_HDCP_STATUS_HDCP2_H_PRIME_PENDING;
	}
out:
	return status;
}

static enum mod_hdcp_status check_pairing_info_available(struct mod_hdcp *hdcp)
{
	enum mod_hdcp_status status;
	uint8_t size;

	status = mod_hdcp_read_rxstatus(hdcp);
	if (status != MOD_HDCP_STATUS_SUCCESS)
		goto out;

	if (is_dp_hdcp(hdcp)) {
		status = HDCP_2_2_DP_RXSTATUS_PAIRING(hdcp->auth.msg.hdcp2.rxstatus_dp) ?
				MOD_HDCP_STATUS_SUCCESS :
				MOD_HDCP_STATUS_HDCP2_PAIRING_INFO_PENDING;
	} else {
		size = HDCP_2_2_HDMI_RXSTATUS_MSG_SZ_HI(hdcp->auth.msg.hdcp2.rxstatus[1]) << 8 |
		       hdcp->auth.msg.hdcp2.rxstatus[0];
		status = (size == sizeof(hdcp->auth.msg.hdcp2.ake_pairing_info)) ?
				MOD_HDCP_STATUS_SUCCESS :
				MOD_HDCP_STATUS_HDCP2_PAIRING_INFO_PENDING;
	}
out:
	return status;
}

static enum mod_hdcp_status poll_l_prime_available(struct mod_hdcp *hdcp)
{
	enum mod_hdcp_status status;
	uint8_t size;
	uint16_t max_wait = 20; // units of ms
	uint16_t num_polls = 5;
	uint16_t wait_time = max_wait / num_polls;

	if (is_dp_hdcp(hdcp))
		status = MOD_HDCP_STATUS_INVALID_OPERATION;
	else
		for (; num_polls; num_polls--) {
			msleep(wait_time);

			status = mod_hdcp_read_rxstatus(hdcp);
			if (status != MOD_HDCP_STATUS_SUCCESS)
				break;

			size = HDCP_2_2_HDMI_RXSTATUS_MSG_SZ_HI(hdcp->auth.msg.hdcp2.rxstatus[1]) << 8 |
			       hdcp->auth.msg.hdcp2.rxstatus[0];
			status = (size == sizeof(hdcp->auth.msg.hdcp2.lc_l_prime)) ?
					MOD_HDCP_STATUS_SUCCESS :
					MOD_HDCP_STATUS_HDCP2_L_PRIME_PENDING;
			if (status == MOD_HDCP_STATUS_SUCCESS)
				break;
		}
	return status;
}

static enum mod_hdcp_status check_stream_ready_available(struct mod_hdcp *hdcp)
{
	enum mod_hdcp_status status;
	uint8_t size;

	if (is_dp_hdcp(hdcp)) {
		status = MOD_HDCP_STATUS_INVALID_OPERATION;
	} else {
		status = mod_hdcp_read_rxstatus(hdcp);
		if (status != MOD_HDCP_STATUS_SUCCESS)
			goto out;
		size = HDCP_2_2_HDMI_RXSTATUS_MSG_SZ_HI(hdcp->auth.msg.hdcp2.rxstatus[1]) << 8 |
		       hdcp->auth.msg.hdcp2.rxstatus[0];
		status = (size == sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready)) ?
				MOD_HDCP_STATUS_SUCCESS :
				MOD_HDCP_STATUS_HDCP2_STREAM_READY_PENDING;
	}
out:
	return status;
}

static inline uint8_t get_device_count(struct mod_hdcp *hdcp)
{
	return HDCP_2_2_DEV_COUNT_LO(hdcp->auth.msg.hdcp2.rx_id_list[2]) +
			(HDCP_2_2_DEV_COUNT_HI(hdcp->auth.msg.hdcp2.rx_id_list[1]) << 4);
}

static enum mod_hdcp_status check_device_count(struct mod_hdcp *hdcp)
{
	/* device count must be greater than or equal to tracked hdcp displays */
	return (get_device_count(hdcp) < get_active_display_count(hdcp)) ?
			MOD_HDCP_STATUS_HDCP2_DEVICE_COUNT_MISMATCH_FAILURE :
			MOD_HDCP_STATUS_SUCCESS;
}

static uint8_t process_rxstatus(struct mod_hdcp *hdcp,
		struct mod_hdcp_event_context *event_ctx,
		struct mod_hdcp_transition_input_hdcp2 *input,
		enum mod_hdcp_status *status)
{
	if (!mod_hdcp_execute_and_set(mod_hdcp_read_rxstatus,
			&input->rxstatus_read, status,
			hdcp, "rxstatus_read"))
		goto out;
	if (!mod_hdcp_execute_and_set(check_reauthentication_request,
			&input->reauth_request_check, status,
			hdcp, "reauth_request_check"))
		goto out;
	if (is_dp_hdcp(hdcp)) {
		if (!mod_hdcp_execute_and_set(check_link_integrity_failure_dp,
				&input->link_integrity_check_dp, status,
				hdcp, "link_integrity_check_dp"))
			goto out;
	}
	if (hdcp->connection.is_repeater)
		if (check_receiver_id_list_ready(hdcp) ==
				MOD_HDCP_STATUS_SUCCESS) {
			HDCP_INPUT_PASS_TRACE(hdcp, "rx_id_list_ready");
			event_ctx->rx_id_list_ready = 1;
			if (is_dp_hdcp(hdcp))
				hdcp->auth.msg.hdcp2.rx_id_list_size =
						sizeof(hdcp->auth.msg.hdcp2.rx_id_list);
			else
				hdcp->auth.msg.hdcp2.rx_id_list_size =
					HDCP_2_2_HDMI_RXSTATUS_MSG_SZ_HI(hdcp->auth.msg.hdcp2.rxstatus[1]) << 8 |
					hdcp->auth.msg.hdcp2.rxstatus[0];
		}
out:
	return (*status == MOD_HDCP_STATUS_SUCCESS);
}

static enum mod_hdcp_status known_hdcp2_capable_rx(struct mod_hdcp *hdcp,
		struct mod_hdcp_event_context *event_ctx,
		struct mod_hdcp_transition_input_hdcp2 *input)
{
	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;

	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
		event_ctx->unexpected_event = 1;
		goto out;
	}

	if (!mod_hdcp_execute_and_set(mod_hdcp_read_hdcp2version,
			&input->hdcp2version_read, &status,
			hdcp, "hdcp2version_read"))
		goto out;
	if (!mod_hdcp_execute_and_set(check_hdcp2_capable,
			&input->hdcp2_capable_check, &status,
			hdcp, "hdcp2_capable"))
		goto out;
out:
	return status;
}

static enum mod_hdcp_status send_ake_init(struct mod_hdcp *hdcp,
		struct mod_hdcp_event_context *event_ctx,
		struct mod_hdcp_transition_input_hdcp2 *input)
{
	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;

	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
		event_ctx->unexpected_event = 1;
		goto out;
	}

	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_create_session,
			&input->create_session, &status,
			hdcp, "create_session"))
		goto out;
	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_prepare_ake_init,
			&input->ake_init_prepare, &status,
			hdcp, "ake_init_prepare"))
		goto out;
	if (!mod_hdcp_execute_and_set(mod_hdcp_write_ake_init,
			&input->ake_init_write, &status,
			hdcp, "ake_init_write"))
		goto out;
out:
	return status;
}

static enum mod_hdcp_status validate_ake_cert(struct mod_hdcp *hdcp,
		struct mod_hdcp_event_context *event_ctx,
		struct mod_hdcp_transition_input_hdcp2 *input)
{
	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;


	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
			event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
		event_ctx->unexpected_event = 1;
		goto out;
	}

	if (is_hdmi_dvi_sl_hdcp(hdcp))
		if (!mod_hdcp_execute_and_set(check_ake_cert_available,
				&input->ake_cert_available, &status,
				hdcp, "ake_cert_available"))
			goto out;
	if (!mod_hdcp_execute_and_set(mod_hdcp_read_ake_cert,
			&input->ake_cert_read, &status,
			hdcp, "ake_cert_read"))
		goto out;
	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_validate_ake_cert,
			&input->ake_cert_validation, &status,
			hdcp, "ake_cert_validation"))
		goto out;
out:
	return status;
}

static enum mod_hdcp_status send_no_stored_km(struct mod_hdcp *hdcp,
		struct mod_hdcp_event_context *event_ctx,
		struct mod_hdcp_transition_input_hdcp2 *input)
{
	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;

	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
		event_ctx->unexpected_event = 1;
		goto out;
	}

	if (!mod_hdcp_execute_and_set(mod_hdcp_write_no_stored_km,
			&input->no_stored_km_write, &status,
			hdcp, "no_stored_km_write"))
		goto out;
out:
	return status;
}

static enum mod_hdcp_status read_h_prime(struct mod_hdcp *hdcp,
		struct mod_hdcp_event_context *event_ctx,
		struct mod_hdcp_transition_input_hdcp2 *input)
{
	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;

	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
			event_ctx->event != MOD_HDCP_EVENT_CPIRQ &&
			event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
		event_ctx->unexpected_event = 1;
		goto out;
	}

	if (!mod_hdcp_execute_and_set(check_h_prime_available,
			&input->h_prime_available, &status,
			hdcp, "h_prime_available"))
		goto out;

	if (!mod_hdcp_execute_and_set(mod_hdcp_read_h_prime,
			&input->h_prime_read, &status,
			hdcp, "h_prime_read"))
		goto out;
out:
	return status;
}

static enum mod_hdcp_status read_pairing_info_and_validate_h_prime(
		struct mod_hdcp *hdcp,
		struct mod_hdcp_event_context *event_ctx,
		struct mod_hdcp_transition_input_hdcp2 *input)
{
	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;

	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
			event_ctx->event != MOD_HDCP_EVENT_CPIRQ &&
			event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
		event_ctx->unexpected_event = 1;
		goto out;
	}

	if (!mod_hdcp_execute_and_set(check_pairing_info_available,
			&input->pairing_available, &status,
			hdcp, "pairing_available"))
		goto out;
	if (!mod_hdcp_execute_and_set(mod_hdcp_read_pairing_info,
			&input->pairing_info_read, &status,
			hdcp, "pairing_info_read"))
		goto out;
	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_validate_h_prime,
			&input->h_prime_validation, &status,
			hdcp, "h_prime_validation"))
		goto out;
out:
	return status;
}

static enum mod_hdcp_status send_stored_km(struct mod_hdcp *hdcp,
		struct mod_hdcp_event_context *event_ctx,
		struct mod_hdcp_transition_input_hdcp2 *input)
{
	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;

	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
		event_ctx->unexpected_event = 1;
		goto out;
	}

	if (!mod_hdcp_execute_and_set(mod_hdcp_write_stored_km,
			&input->stored_km_write, &status,
			hdcp, "stored_km_write"))
		goto out;
out:
	return status;
}

static enum mod_hdcp_status validate_h_prime(struct mod_hdcp *hdcp,
		struct mod_hdcp_event_context *event_ctx,
		struct mod_hdcp_transition_input_hdcp2 *input)
{
	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;

	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
			event_ctx->event != MOD_HDCP_EVENT_CPIRQ &&
			event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
		event_ctx->unexpected_event = 1;
		goto out;
	}

	if (!mod_hdcp_execute_and_set(check_h_prime_available,
			&input->h_prime_available, &status,
			hdcp, "h_prime_available"))
		goto out;
	if (!mod_hdcp_execute_and_set(mod_hdcp_read_h_prime,
			&input->h_prime_read, &status,
			hdcp, "h_prime_read"))
		goto out;
	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_validate_h_prime,
			&input->h_prime_validation, &status,
			hdcp, "h_prime_validation"))
		goto out;
out:
	return status;
}

static enum mod_hdcp_status locality_check(struct mod_hdcp *hdcp,
		struct mod_hdcp_event_context *event_ctx,
		struct mod_hdcp_transition_input_hdcp2 *input)
{
	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;

	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
		event_ctx->unexpected_event = 1;
		goto out;
	}

	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_prepare_lc_init,
			&input->lc_init_prepare, &status,
			hdcp, "lc_init_prepare"))
		goto out;
	if (!mod_hdcp_execute_and_set(mod_hdcp_write_lc_init,
			&input->lc_init_write, &status,
			 hdcp, "lc_init_write"))
		goto out;
	if (is_dp_hdcp(hdcp))
		msleep(16);
	else
		if (!mod_hdcp_execute_and_set(poll_l_prime_available,
				&input->l_prime_available_poll, &status,
				hdcp, "l_prime_available_poll"))
			goto out;
	if (!mod_hdcp_execute_and_set(mod_hdcp_read_l_prime,
			&input->l_prime_read, &status,
			hdcp, "l_prime_read"))
		goto out;
	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_validate_l_prime,
			&input->l_prime_validation, &status,
			hdcp, "l_prime_validation"))
		goto out;
out:
	return status;
}

static enum mod_hdcp_status exchange_ks_and_test_for_repeater(struct mod_hdcp *hdcp,
		struct mod_hdcp_event_context *event_ctx,
		struct mod_hdcp_transition_input_hdcp2 *input)
{
	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;

	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
		event_ctx->unexpected_event = 1;
		goto out;
	}

	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_prepare_eks,
			&input->eks_prepare, &status,
			hdcp, "eks_prepare"))
		goto out;
	if (!mod_hdcp_execute_and_set(mod_hdcp_write_eks,
			&input->eks_write, &status,
			hdcp, "eks_write"))
		goto out;
out:
	return status;
}

static enum mod_hdcp_status enable_encryption(struct mod_hdcp *hdcp,
		struct mod_hdcp_event_context *event_ctx,
		struct mod_hdcp_transition_input_hdcp2 *input)
{
	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;

	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
			event_ctx->event != MOD_HDCP_EVENT_CPIRQ) {
		event_ctx->unexpected_event = 1;
		goto out;
	}
	if (event_ctx->event == MOD_HDCP_EVENT_CPIRQ) {
		process_rxstatus(hdcp, event_ctx, input, &status);
		goto out;
	}

	if (is_hdmi_dvi_sl_hdcp(hdcp)) {
		if (!process_rxstatus(hdcp, event_ctx, input, &status))
			goto out;
		if (event_ctx->rx_id_list_ready)
			goto out;
	}
	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_enable_encryption,
			&input->enable_encryption, &status,
			hdcp, "enable_encryption"))
		goto out;
	if (is_dp_mst_hdcp(hdcp)) {
		if (!mod_hdcp_execute_and_set(
				mod_hdcp_hdcp2_enable_dp_stream_encryption,
				&input->stream_encryption_dp, &status,
				hdcp, "stream_encryption_dp"))
			goto out;
	}
out:
	return status;
}

static enum mod_hdcp_status authenticated(struct mod_hdcp *hdcp,
		struct mod_hdcp_event_context *event_ctx,
		struct mod_hdcp_transition_input_hdcp2 *input)
{
	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;

	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
			event_ctx->event != MOD_HDCP_EVENT_CPIRQ) {
		event_ctx->unexpected_event = 1;
		goto out;
	}

	if (!process_rxstatus(hdcp, event_ctx, input, &status))
		goto out;
	if (event_ctx->rx_id_list_ready)
		goto out;
out:
	return status;
}

static enum mod_hdcp_status wait_for_rx_id_list(struct mod_hdcp *hdcp,
		struct mod_hdcp_event_context *event_ctx,
		struct mod_hdcp_transition_input_hdcp2 *input)
{
	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;

	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
			event_ctx->event != MOD_HDCP_EVENT_CPIRQ &&
			event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
		event_ctx->unexpected_event = 1;
		goto out;
	}

	if (!process_rxstatus(hdcp, event_ctx, input, &status))
		goto out;
	if (!event_ctx->rx_id_list_ready) {
		status = MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_NOT_READY;
		goto out;
	}
out:
	return status;
}

static enum mod_hdcp_status verify_rx_id_list_and_send_ack(struct mod_hdcp *hdcp,
		struct mod_hdcp_event_context *event_ctx,
		struct mod_hdcp_transition_input_hdcp2 *input)
{
	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;

	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
			event_ctx->event != MOD_HDCP_EVENT_CPIRQ) {
		event_ctx->unexpected_event = 1;
		goto out;
	}
	if (event_ctx->event == MOD_HDCP_EVENT_CPIRQ) {
		process_rxstatus(hdcp, event_ctx, input, &status);
		goto out;
	}

	if (!mod_hdcp_execute_and_set(mod_hdcp_read_rx_id_list,
			&input->rx_id_list_read,
			&status, hdcp, "receiver_id_list_read"))
		goto out;
	if (!mod_hdcp_execute_and_set(check_device_count,
			&input->device_count_check,
			&status, hdcp, "device_count_check"))
		goto out;
	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_validate_rx_id_list,
			&input->rx_id_list_validation,
			&status, hdcp, "rx_id_list_validation"))
		goto out;
	if (!mod_hdcp_execute_and_set(mod_hdcp_write_repeater_auth_ack,
			&input->repeater_auth_ack_write,
			&status, hdcp, "repeater_auth_ack_write"))
		goto out;
out:
	return status;
}

static enum mod_hdcp_status send_stream_management(struct mod_hdcp *hdcp,
		struct mod_hdcp_event_context *event_ctx,
		struct mod_hdcp_transition_input_hdcp2 *input)
{
	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;

	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
			event_ctx->event != MOD_HDCP_EVENT_CPIRQ) {
		event_ctx->unexpected_event = 1;
		goto out;
	}
	if (event_ctx->event == MOD_HDCP_EVENT_CPIRQ) {
		process_rxstatus(hdcp, event_ctx, input, &status);
		goto out;
	}

	if (is_hdmi_dvi_sl_hdcp(hdcp)) {
		if (!process_rxstatus(hdcp, event_ctx, input, &status))
			goto out;
		if (event_ctx->rx_id_list_ready)
			goto out;
	}
	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_prepare_stream_management,
			&input->prepare_stream_manage,
			&status, hdcp, "prepare_stream_manage"))
		goto out;

	if (!mod_hdcp_execute_and_set(mod_hdcp_write_stream_manage,
			&input->stream_manage_write,
			&status, hdcp, "stream_manage_write"))
		goto out;
out:
	return status;
}

static enum mod_hdcp_status validate_stream_ready(struct mod_hdcp *hdcp,
		struct mod_hdcp_event_context *event_ctx,
		struct mod_hdcp_transition_input_hdcp2 *input)
{
	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;

	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
			event_ctx->event != MOD_HDCP_EVENT_CPIRQ &&
			event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
		event_ctx->unexpected_event = 1;
		goto out;
	}
	if (event_ctx->event == MOD_HDCP_EVENT_CPIRQ) {
		process_rxstatus(hdcp, event_ctx, input, &status);
		goto out;
	}

	if (is_hdmi_dvi_sl_hdcp(hdcp)) {
		if (!process_rxstatus(hdcp, event_ctx, input, &status))
			goto out;
		if (event_ctx->rx_id_list_ready) {
			goto out;
		}
	}
	if (is_hdmi_dvi_sl_hdcp(hdcp))
		if (!mod_hdcp_execute_and_set(check_stream_ready_available,
				&input->stream_ready_available,
				&status, hdcp, "stream_ready_available"))
			goto out;
	if (!mod_hdcp_execute_and_set(mod_hdcp_read_stream_ready,
			&input->stream_ready_read,
			&status, hdcp, "stream_ready_read"))
		goto out;
	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_validate_stream_ready,
			&input->stream_ready_validation,
			&status, hdcp, "stream_ready_validation"))
		goto out;

out:
	return status;
}

static enum mod_hdcp_status determine_rx_hdcp_capable_dp(struct mod_hdcp *hdcp,
		struct mod_hdcp_event_context *event_ctx,
		struct mod_hdcp_transition_input_hdcp2 *input)
{
	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;

	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
		event_ctx->unexpected_event = 1;
		goto out;
	}

	if (!mod_hdcp_execute_and_set(mod_hdcp_read_rxcaps,
			&input->rx_caps_read_dp,
			&status, hdcp, "rx_caps_read_dp"))
		goto out;
	if (!mod_hdcp_execute_and_set(check_hdcp2_capable,
			&input->hdcp2_capable_check, &status,
			hdcp, "hdcp2_capable_check"))
		goto out;
out:
	return status;
}

static enum mod_hdcp_status send_content_stream_type_dp(struct mod_hdcp *hdcp,
		struct mod_hdcp_event_context *event_ctx,
		struct mod_hdcp_transition_input_hdcp2 *input)
{
	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;

	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
			event_ctx->event != MOD_HDCP_EVENT_CPIRQ) {
		event_ctx->unexpected_event = 1;
		goto out;
	}

	if (!process_rxstatus(hdcp, event_ctx, input, &status))
		goto out;
	if (!mod_hdcp_execute_and_set(mod_hdcp_write_content_type,
			&input->content_stream_type_write, &status,
			hdcp, "content_stream_type_write"))
		goto out;
out:
	return status;
}

enum mod_hdcp_status mod_hdcp_hdcp2_execution(struct mod_hdcp *hdcp,
	struct mod_hdcp_event_context *event_ctx,
	struct mod_hdcp_transition_input_hdcp2 *input)
{
	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;

	switch (current_state(hdcp)) {
	case H2_A0_KNOWN_HDCP2_CAPABLE_RX:
		status = known_hdcp2_capable_rx(hdcp, event_ctx, input);
		break;
	case H2_A1_SEND_AKE_INIT:
		status = send_ake_init(hdcp, event_ctx, input);
		break;
	case H2_A1_VALIDATE_AKE_CERT:
		status = validate_ake_cert(hdcp, event_ctx, input);
		break;
	case H2_A1_SEND_NO_STORED_KM:
		status = send_no_stored_km(hdcp, event_ctx, input);
		break;
	case H2_A1_READ_H_PRIME:
		status = read_h_prime(hdcp, event_ctx, input);
		break;
	case H2_A1_READ_PAIRING_INFO_AND_VALIDATE_H_PRIME:
		status = read_pairing_info_and_validate_h_prime(hdcp,
				event_ctx, input);
		break;
	case H2_A1_SEND_STORED_KM:
		status = send_stored_km(hdcp, event_ctx, input);
		break;
	case H2_A1_VALIDATE_H_PRIME:
		status = validate_h_prime(hdcp, event_ctx, input);
		break;
	case H2_A2_LOCALITY_CHECK:
		status = locality_check(hdcp, event_ctx, input);
		break;
	case H2_A3_EXCHANGE_KS_AND_TEST_FOR_REPEATER:
		status = exchange_ks_and_test_for_repeater(hdcp, event_ctx, input);
		break;
	case H2_ENABLE_ENCRYPTION:
		status = enable_encryption(hdcp, event_ctx, input);
		break;
	case H2_A5_AUTHENTICATED:
		status = authenticated(hdcp, event_ctx, input);
		break;
	case H2_A6_WAIT_FOR_RX_ID_LIST:
		status = wait_for_rx_id_list(hdcp, event_ctx, input);
		break;
	case H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK:
		status = verify_rx_id_list_and_send_ack(hdcp, event_ctx, input);
		break;
	case H2_A9_SEND_STREAM_MANAGEMENT:
		status = send_stream_management(hdcp, event_ctx, input);
		break;
	case H2_A9_VALIDATE_STREAM_READY:
		status = validate_stream_ready(hdcp, event_ctx, input);
		break;
	default:
		status = MOD_HDCP_STATUS_INVALID_STATE;
		break;
	}

	return status;
}

enum mod_hdcp_status mod_hdcp_hdcp2_dp_execution(struct mod_hdcp *hdcp,
	struct mod_hdcp_event_context *event_ctx,
	struct mod_hdcp_transition_input_hdcp2 *input)
{
	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;

	switch (current_state(hdcp)) {
	case D2_A0_DETERMINE_RX_HDCP_CAPABLE:
		status = determine_rx_hdcp_capable_dp(hdcp, event_ctx, input);
		break;
	case D2_A1_SEND_AKE_INIT:
		status = send_ake_init(hdcp, event_ctx, input);
		break;
	case D2_A1_VALIDATE_AKE_CERT:
		status = validate_ake_cert(hdcp, event_ctx, input);
		break;
	case D2_A1_SEND_NO_STORED_KM:
		status = send_no_stored_km(hdcp, event_ctx, input);
		break;
	case D2_A1_READ_H_PRIME:
		status = read_h_prime(hdcp, event_ctx, input);
		break;
	case D2_A1_READ_PAIRING_INFO_AND_VALIDATE_H_PRIME:
		status = read_pairing_info_and_validate_h_prime(hdcp,
				event_ctx, input);
		break;
	case D2_A1_SEND_STORED_KM:
		status = send_stored_km(hdcp, event_ctx, input);
		break;
	case D2_A1_VALIDATE_H_PRIME:
		status = validate_h_prime(hdcp, event_ctx, input);
		break;
	case D2_A2_LOCALITY_CHECK:
		status = locality_check(hdcp, event_ctx, input);
		break;
	case D2_A34_EXCHANGE_KS_AND_TEST_FOR_REPEATER:
		status = exchange_ks_and_test_for_repeater(hdcp,
				event_ctx, input);
		break;
	case D2_SEND_CONTENT_STREAM_TYPE:
		status = send_content_stream_type_dp(hdcp, event_ctx, input);
		break;
	case D2_ENABLE_ENCRYPTION:
		status = enable_encryption(hdcp, event_ctx, input);
		break;
	case D2_A5_AUTHENTICATED:
		status = authenticated(hdcp, event_ctx, input);
		break;
	case D2_A6_WAIT_FOR_RX_ID_LIST:
		status = wait_for_rx_id_list(hdcp, event_ctx, input);
		break;
	case D2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK:
		status = verify_rx_id_list_and_send_ack(hdcp, event_ctx, input);
		break;
	case D2_A9_SEND_STREAM_MANAGEMENT:
		status = send_stream_management(hdcp, event_ctx, input);
		break;
	case D2_A9_VALIDATE_STREAM_READY:
		status = validate_stream_ready(hdcp, event_ctx, input);
		break;
	default:
		status = MOD_HDCP_STATUS_INVALID_STATE;
		break;
	}

	return status;
}
