[PATCH v2 2/3] Subject: [PATCH] drm/mediatek/dp: Add HDCP2.x feature for DisplayPort

CK Hu (胡俊光) ck.hu at mediatek.com
Mon Feb 19 01:33:49 PST 2024


Hi, Mac:

On Mon, 2024-02-05 at 13:50 +0800, mac.shen wrote:
> Add HDCP2.x feature for DisplayPort.
> When userspace request the kernel protect future content communicated
> over the link with Content_Protection property, the feature will do
> HDCP2.x authentication if the sink support HDCP2.X.
> 
> Changes in v2:
> - remove switch case, and refine code to make more clear
> - remove some definitions, and use the definitions in
>   include/drm/drm_hdcp.h
> - use the struct which defined in include/drm/drm_hdcp.h
> - do HDCP2.x authentication when userspace request the
>   kernel protect future content communicated
> per suggestion from the previous thread:
> https://lore.kernel.org/all/8fff59b5567449d8201dd1138c8fa
> 9218a545c46.camel at mediatek.com/
> 
> Signed-off-by: mac.shen <mac.shen at mediatek.com>
> ---

[snip]

> +
> +int dp_tx_hdcp2_fsm(struct mtk_hdcp_info *hdcp_info)
> +{
> +	static u32 timeout_value;
> +	static u8 pre_main;
> +	static u8 pre_sub;
> +	static u32 pre_time;
> +	int err_code = HDCP_ERR_NONE;
> +	bool stored = false;
> +	u32 time;
> +	int ret = 0;
> +	bool tmp = false;
> +
> +	if (pre_main != hdcp_info->hdcp2_info.hdcp_handler.main_state
> ||
> +	    hdcp_info->hdcp2_info.hdcp_handler.sub_state != pre_sub) {
> +		DPTXHDCPMSG("2.x: Port(M : S)= (%d, %d)",
> +			    hdcp_info-
> >hdcp2_info.hdcp_handler.main_state,
> +			    hdcp_info-
> >hdcp2_info.hdcp_handler.sub_state);
> +		pre_main = hdcp_info-
> >hdcp2_info.hdcp_handler.main_state;
> +		pre_sub = hdcp_info->hdcp2_info.hdcp_handler.sub_state;
> +	}
> +
> +	switch (hdcp_info->hdcp2_info.hdcp_handler.main_state) {
> +	case HDCP2_MS_H1P1:
> +		/* HDCP2_MS_H1P1 */
> +		/* HDCP_2_2_AUTH_FAIL */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_AUTH_FAIL) {
> +			pr_err("2.x: Authentication Fail!\n");
> +			dp_tx_hdcp2_enable_auth(hdcp_info, false);
> +			hdcp_info->auth_status = AUTH_FAIL;
> +		}
> +		break;
> +
> +	case HDCP2_MS_A0F0:
> +		/* HDCP2_MS_A0F0 */
> +		/* HDCP_2_2_NULL_MSG */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_NULL_MSG) {

Could you refer to intel driver to get rid of this state machine? It
seams this flow does not need state machine. Just step forward. If
error happen, break the flow. If your implement is like intel driver,
it's easier for me to compare and easier to review.

[1] 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/gpu/drm/i915/display/intel_hdcp.c?h=v6.8-rc5#n1868

Regards,
CK

> +			if (!hdcp_info->hdcp2_info.enable) {
> +				dp_tx_hdcp2_set_state(hdcp_info,
> HDCP2_MS_H1P1, HDCP_2_2_AUTH_FAIL);
> +				DPTXHDCPMSG("2.x: Sink Doesn't Support
> Hdcp2x!\n");
> +				break;
> +			}
> +
> +			dp_tx_hdcp2_init(hdcp_info);
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A1F1,
> HDCP_2_2_NULL_MSG);
> +			DPTXHDCPMSG("2.x: Sink Support Hdcp2x!\n");
> +		}
> +		break;
> +
> +	case HDCP2_MS_A1F1:
> +		/* HDCP2_MS_A1F1 */
> +		/* HDCP_2_2_NULL_MSG */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_NULL_MSG) {
> +			if (hdcp_info->hdcp2_info.retry_count >=
> HDCP2_TX_RETRY_CNT) {
> +				dp_tx_hdcp2_set_state(hdcp_info,
> HDCP2_MS_H1P1, HDCP_2_2_AUTH_FAIL);
> +				pr_err("2.x: Try Max Count\n");
> +				break;
> +			}
> +
> +			hdcp_info->hdcp2_info.retry_count++;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A1F1,
> HDCP_2_2_AKE_INIT);
> +		}
> +
> +		/* HDCP2_MS_A1F1 */
> +		/* HDCP_2_2_AKE_INIT */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_AKE_INIT) {
> +			tmp = dp_tx_hdcp2_write_msg(hdcp_info,
> HDCP_2_2_AKE_INIT);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_SEND_MSG_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +			dp_tx_hdcp2_rest_variable(hdcp_info);
> +			hdcp_info->hdcp2_info.read_certrx = true;
> +
> +			hdcp_info-
> >hdcp2_info.hdcp_handler.send_ake_init = true;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A1F1,
> HDCP_2_2_AKE_SEND_CERT);
> +			pre_time = mtk_dp_get_system_time();
> +		}
> +
> +		/* HDCP2_MS_A1F1 */
> +		/* HDCP_2_2_AKE_SEND_CERT */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_AKE_SEND_CERT) {
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time < HDCP_2_2_CERT_TIMEOUT_MS) {
> +				msleep(20);
> +				break;
> +			}
> +			if (hdcp_info->hdcp2_info.read_certrx)
> +				dp_tx_hdcp2_read_msg(hdcp_info,
> HDCP_2_2_AKE_SEND_CERT);
> +
> +			if (!hdcp_info-
> >hdcp2_info.hdcp_handler.recv_msg)
> +				break;
> +
> +			ret = tee_ake_certificate(hdcp_info,
> +						  (u8 *)&hdcp_info-
> >hdcp2_info.hdcp_rx.cert_rx,
> +						  &stored,
> +				hdcp_info-
> >hdcp2_info.ake_stored_km.e_kh_km_m +
> +				HDCP_2_2_E_KH_KM_LEN,
> +				hdcp_info-
> >hdcp2_info.ake_stored_km.e_kh_km_m);
> +
> +			if (ret != RET_COMPARE_PASS) {
> +				err_code = HDCP_ERR_PROCESS_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			hdcp_info->hdcp2_info.hdcp_handler.stored_km =
> stored;
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg =
> false;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A1F1,
> +					      hdcp_info-
> >hdcp2_info.hdcp_handler.stored_km ?
> +					HDCP_2_2_AKE_STORED_KM :
> +					HDCP_2_2_AKE_NO_STORED_KM);
> +		}
> +
> +		/* HDCP2_MS_A1F1 */
> +		/* HDCP_2_2_AKE_NO_STORED_KM */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_AKE_NO_STORED_KM) {
> +			DPTXHDCPMSG("2.x: Get Km, derive Ekpub(km)\n");
> +
> +			tee_enc_rsaes_oaep(hdcp_info,
> +					   hdcp_info-
> >hdcp2_info.hdcp_tx.no_stored_km.e_kpub_km);
> +			/* Prepare e_kpub_km to send */
> +			tmp = dp_tx_hdcp2_write_msg(hdcp_info,
> HDCP_2_2_AKE_NO_STORED_KM);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_SEND_MSG_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A1F1,
> HDCP_2_2_AKE_SEND_HPRIME);
> +			timeout_value =
> HDCP_2_2_HPRIME_NO_PAIRED_TIMEOUT_MS;
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg =
> false;
> +			pre_time = mtk_dp_get_system_time();
> +		}
> +
> +		/* HDCP2_MS_A1F1 */
> +		/* HDCP_2_2_AKE_STORED_KM */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_AKE_STORED_KM) {
> +			/* Prepare ekh_km & M to send */
> +			tmp = dp_tx_hdcp2_write_msg(hdcp_info,
> HDCP_2_2_AKE_STORED_KM);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_SEND_MSG_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			err_code = HDCP_ERR_NONE;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A1F1,
> HDCP_2_2_AKE_SEND_HPRIME);
> +			timeout_value =
> HDCP_2_2_HPRIME_PAIRED_TIMEOUT_MS;
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg =
> false;
> +			pre_time = mtk_dp_get_system_time();
> +		}
> +
> +		/* HDCP2_MS_A1F1 */
> +		/* HDCP_2_2_AKE_SEND_HPRIME */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_AKE_SEND_HPRIME) {
> +			if (hdcp_info->hdcp2_info.read_h_prime)
> +				dp_tx_hdcp2_read_msg(hdcp_info,
> HDCP_2_2_AKE_SEND_HPRIME);
> +
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time > timeout_value) {
> +				err_code = HDCP_ERR_RESPONSE_TIMEROUT;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			if (!hdcp_info-
> >hdcp2_info.hdcp_handler.recv_msg)
> +				break;
> +
> +			ret = tee_ake_h_prime(hdcp_info,
> +					      hdcp_info-
> >hdcp2_info.hdcp_tx.ake_init.r_tx,
> +					      hdcp_info-
> >hdcp2_info.hdcp_rx.send_cert.r_rx,
> +				hdcp_info-
> >hdcp2_info.hdcp_rx.send_cert.rx_caps,
> +				(u8 *)&hdcp_info-
> >hdcp2_info.hdcp_tx.tx_caps,
> +				hdcp_info-
> >hdcp2_info.hdcp_rx.send_hprime.h_prime,
> +				HDCP_2_2_H_PRIME_LEN);
> +			if (ret != RET_COMPARE_PASS) {
> +				if (hdcp_info-
> >hdcp2_info.hdcp_handler.stored_km)
> +					tee_clear_paring(hdcp_info);
> +				err_code = HDCP_ERR_PROCESS_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			if (hdcp_info-
> >hdcp2_info.hdcp_handler.stored_km)
> +				dp_tx_hdcp2_set_state(hdcp_info,
> HDCP2_MS_A2F2, HDCP_2_2_LC_INIT);
> +			else
> +				dp_tx_hdcp2_set_state(hdcp_info,
> HDCP2_MS_A1F1,
> +						      HDCP_2_2_AKE_SEND
> _PAIRING_INFO);
> +
> +			pre_time = mtk_dp_get_system_time();
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg =
> false;
> +		}
> +
> +		/* HDCP2_MS_A1F1 */
> +		/* HDCP_2_2_AKE_SEND_PAIRING_INFO */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> +			HDCP_2_2_AKE_SEND_PAIRING_INFO) {
> +			if (hdcp_info->hdcp2_info.read_pairing)
> +				dp_tx_hdcp2_read_msg(hdcp_info,
> HDCP_2_2_AKE_SEND_PAIRING_INFO);
> +
> +			/* Ekh_Km must be available less than 200ms,
> Give mode time for some Rx */
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time >	HDCP_2_2_PAIRING_TIMEOUT_MS *
> 2) {
> +				err_code = HDCP_ERR_RESPONSE_TIMEROUT;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			if (!hdcp_info-
> >hdcp2_info.hdcp_handler.recv_msg)
> +				break;
> +
> +			/* Store m, km, Ekh(km) */
> +			tee_ake_paring(hdcp_info,
> +				       hdcp_info-
> >hdcp2_info.hdcp_rx.pairing_info.e_kh_km);
> +
> +			hdcp_info->hdcp2_info.hdcp_handler.send_pair =
> true;
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg =
> false;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A2F2,
> HDCP_2_2_LC_INIT);
> +			pre_time = mtk_dp_get_system_time();
> +		}
> +		break;
> +
> +	case HDCP2_MS_A2F2:
> +		/* HDCP2_MS_A2F2 */
> +		/* HDCP_2_2_LC_INIT */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_LC_INIT) {
> +			/* prepare Rn to send */
> +			tmp = dp_tx_hdcp2_write_msg(hdcp_info,
> HDCP_2_2_LC_INIT);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_SEND_MSG_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +			hdcp_info->hdcp2_info.hdcp_handler.send_lc_init 
> = true;
> +
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A2F2,
> HDCP_2_2_LC_SEND_LPRIME);
> +			pre_time = mtk_dp_get_system_time();
> +		}
> +
> +		/* HDCP2_MS_A2F2 */
> +		/* HDCP_2_2_LC_SEND_LPRIME */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_LC_SEND_LPRIME) {
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time < HDCP_2_2_DP_HPRIME_READ_TIMEOUT_MS)
> +				break;
> +
> +			if (hdcp_info->hdcp2_info.read_l_prime)
> +				dp_tx_hdcp2_read_msg(hdcp_info,
> HDCP_2_2_LC_SEND_LPRIME);
> +
> +			if (!hdcp_info-
> >hdcp2_info.hdcp_handler.recv_msg)
> +				break;
> +
> +			ret = tee_lc_l_prime(hdcp_info, hdcp_info-
> >hdcp2_info.hdcp_tx.lc_init.r_n,
> +					     hdcp_info-
> >hdcp2_info.hdcp_rx.send_lprime.l_prime,
> +					     HDCP_2_2_L_PRIME_LEN);
> +			if (ret != RET_COMPARE_PASS) {
> +				err_code = HDCP_ERR_PROCESS_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			DPTXHDCPMSG("2.x: L' is PASS!!\n");
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg =
> false;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A3F3,
> HDCP_2_2_NULL_MSG);
> +			pre_time = mtk_dp_get_system_time();
> +		}
> +		break;
> +
> +	case HDCP2_MS_A3F3:
> +		/* HDCP2_MS_A3F3 */
> +		/* HDCP_2_2_NULL_MSG */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_NULL_MSG) {
> +			tee_ske_enc_ks(hdcp_info, hdcp_info-
> >hdcp2_info.hdcp_tx.send_eks.riv,
> +				       hdcp_info-
> >hdcp2_info.hdcp_tx.send_eks.e_dkey_ks);
> +
> +			tmp = dp_tx_hdcp2_write_msg(hdcp_info,
> HDCP_2_2_SKE_SEND_EKS);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_SEND_MSG_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			if (!hdcp_info->hdcp2_info.repeater)
> +				dp_tx_hdcp2_write_msg(hdcp_info,
> HDCP_2_2_STREAM_TYPE);
> +
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A3F3,
> HDCP_2_2_SKE_SEND_EKS);
> +			pre_time = mtk_dp_get_system_time();
> +		}
> +
> +		/* HDCP2_MS_A3F3 */
> +		/* HDCP_2_2_SKE_SEND_EKS */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_SKE_SEND_EKS) {
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time >=
> HDCP_2_2_DELAY_BEFORE_ENCRYPTION_EN)
> +				dp_tx_hdcp2_set_state(hdcp_info,
> HDCP2_MS_A4F4, HDCP_2_2_NULL_MSG);
> +		}
> +		break;
> +
> +	case HDCP2_MS_A4F4:
> +		/* HDCP2_MS_A4F4 */
> +		/* HDCP_2_2_NULL_MSG */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_NULL_MSG) {
> +			if (!hdcp_info->hdcp2_info.repeater) {
> +				dp_tx_hdcp2_set_state(hdcp_info,
> HDCP2_MS_A5F5, HDCP_2_2_AUTH_DONE);
> +				break;
> +			}
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A6F6,
> +					      HDCP_2_2_REP_SEND_RECVID_
> LIST);
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg =
> false;
> +			pre_time = mtk_dp_get_system_time();
> +		}
> +		break;
> +
> +	case HDCP2_MS_A5F5:
> +		/* HDCP2_MS_A5F5 */
> +		/* HDCP_2_2_AUTH_DONE */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_AUTH_DONE) {
> +			DPTXHDCPMSG("2.x: Authentication done!\n");
> +			hdcp_info->auth_status = AUTH_PASS;
> +			hdcp_info->hdcp2_info.retry_count = 0;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A5F5,
> HDCP_2_2_NULL_MSG);
> +			dp_tx_hdcp2_enable_auth(hdcp_info, true);
> +		}
> +		break;
> +
> +	case HDCP2_MS_A6F6:
> +		/* HDCP2_MS_A6F6 */
> +		/* HDCP_2_2_REP_SEND_RECVID_LIST */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> +			HDCP_2_2_REP_SEND_RECVID_LIST) {
> +			if (hdcp_info->hdcp2_info.read_v_prime)
> +				dp_tx_hdcp2_read_msg(hdcp_info,
> HDCP_2_2_REP_SEND_RECVID_LIST);
> +
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time > HDCP_2_2_RECVID_LIST_TIMEOUT_MS) {
> +				err_code = HDCP_ERR_RESPONSE_TIMEROUT;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			if (!hdcp_info-
> >hdcp2_info.hdcp_handler.recv_msg)
> +				break;
> +
> +			pre_time = mtk_dp_get_system_time();
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg =
> false;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A7F7,
> +					      HDCP_2_2_REP_VERIFY_RECVI
> D_LIST);
> +		}
> +		break;
> +
> +	case HDCP2_MS_A7F7:
> +		/* HDCP2_MS_A7F7 */
> +		/* HDCP_2_2_REP_VERIFY_RECVID_LIST */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> +			HDCP_2_2_REP_VERIFY_RECVID_LIST) {
> +			if ((hdcp_info-
> >hdcp2_info.hdcp_rx.receiverid_list.rx_info[1]
> +				& (BIT(2) | BIT(3))) != 0) {
> +				pr_err("2.x: DEVS_EXCEEDED or
> CASCADE_EXCEDDED!\n");
> +				err_code = HDCP_ERR_PROCESS_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			/* check seqNumV here */
> +			tmp = dp_tx_hdcp2_check_seq_num_v(hdcp_info);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_PROCESS_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			tmp =
> dp_tx_hdcp2_recv_rep_auth_send_recv_id_list(hdcp_info);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_PROCESS_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A8F8,
> HDCP_2_2_REP_SEND_ACK);
> +		}
> +		break;
> +
> +	case HDCP2_MS_A8F8:
> +		/* HDCP2_MS_A8F8 */
> +		/* HDCP_2_2_REP_SEND_ACK */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_REP_SEND_ACK) {
> +			tmp = dp_tx_hdcp2_write_msg(hdcp_info,
> HDCP_2_2_REP_SEND_ACK);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_SEND_MSG_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time > HDCP2_REP_SEND_ACK) {
> +				err_code = HDCP_ERR_RESPONSE_TIMEROUT;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A9F9,
> HDCP_2_2_REP_STREAM_MANAGE);
> +			hdcp_info->hdcp2_info.hdcp_handler.retry_cnt =
> 0;
> +		}
> +		break;
> +
> +	case HDCP2_MS_A9F9:
> +		/* HDCP2_MS_A9F9 */
> +		/* HDCP_2_2_REP_STREAM_MANAGE */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_REP_STREAM_MANAGE) {
> +			tmp =
> dp_tx_hdcp2_process_rep_auth_stream_manage(hdcp_info);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_PROCESS_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			tmp = dp_tx_hdcp2_write_msg(hdcp_info,
> HDCP_2_2_REP_STREAM_MANAGE);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_SEND_MSG_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			pre_time = mtk_dp_get_system_time();
> +			hdcp_info->hdcp2_info.hdcp_handler.recv_msg =
> false;
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A9F9,
> +					      HDCP_2_2_REP_STREAM_READY
> );
> +		}
> +
> +		/* HDCP2_MS_A9F9 */
> +		/* HDCP_2_2_REP_STREAM_READY */
> +		if (hdcp_info->hdcp2_info.hdcp_handler.sub_state ==
> HDCP_2_2_REP_STREAM_READY) {
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time <= HDCP_2_2_STREAM_READY_TIMEOUT_MS /
> 2)
> +				break;
> +
> +			dp_tx_hdcp2_read_msg(hdcp_info,
> HDCP_2_2_REP_STREAM_READY);
> +
> +			time = mtk_dp_get_time_diff(pre_time);
> +			if (time > HDCP_2_2_STREAM_READY_TIMEOUT_MS) {
> +				err_code = HDCP_ERR_RESPONSE_TIMEROUT;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			if (!hdcp_info-
> >hdcp2_info.hdcp_handler.recv_msg) {
> +				if (hdcp_info-
> >hdcp2_info.hdcp_handler.retry_cnt
> +					>=
> HDCP2_STREAM_MANAGE_RETRY_CNT) {
> +					err_code =
> HDCP_ERR_RESPONSE_TIMEROUT;
> +					dp_tx_hdcp2_err_handle(hdcp_inf
> o, err_code, __LINE__);
> +					break;
> +				}
> +
> +				hdcp_info-
> >hdcp2_info.hdcp_handler.retry_cnt++;
> +
> +				dp_tx_hdcp2_set_state(hdcp_info,
> HDCP2_MS_A9F9,
> +						      HDCP_2_2_REP_STRE
> AM_READY);
> +				break;
> +			}
> +
> +			tmp =
> dp_tx_hdcp2_recv_rep_auth_stream_ready(hdcp_info);
> +			if (!tmp) {
> +				err_code = HDCP_ERR_PROCESS_FAIL;
> +				dp_tx_hdcp2_err_handle(hdcp_info,
> err_code, __LINE__);
> +				break;
> +			}
> +
> +			dp_tx_hdcp2_set_state(hdcp_info, HDCP2_MS_A5F5,
> HDCP_2_2_AUTH_DONE);
> +		}
> +		break;
> +
> +	default:
> +		err_code = HDCP_ERR_UNKNOWN_STATE;
> +		dp_tx_hdcp2_err_handle(hdcp_info, err_code, __LINE__);
> +		break;
> +	}
> +
> +	return err_code;
> +}
> +


More information about the Linux-mediatek mailing list