brintos

brintos / linux-shallow public Read only

0
0
Text · 21.0 KiB · 6e064e6 Raw
691 lines · c
1/*2 * Copyright 2019 Advanced Micro Devices, Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 * Authors: AMD23 *24 */25 26#include "hdcp.h"27 28#ifndef MIN29#define MIN(a, b) ((a) < (b) ? (a) : (b))30#endif31#define HDCP_I2C_ADDR 0x3a	/* 0x74 >> 1*/32#define KSV_READ_SIZE 0xf	/* 0x6803b - 0x6802c */33#define HDCP_MAX_AUX_TRANSACTION_SIZE 1634 35#define DP_CP_IRQ (1 << 2)36 37enum mod_hdcp_ddc_message_id {38	MOD_HDCP_MESSAGE_ID_INVALID = -1,39 40	/* HDCP 1.4 */41 42	MOD_HDCP_MESSAGE_ID_READ_BKSV = 0,43	MOD_HDCP_MESSAGE_ID_READ_RI_R0,44	MOD_HDCP_MESSAGE_ID_WRITE_AKSV,45	MOD_HDCP_MESSAGE_ID_WRITE_AINFO,46	MOD_HDCP_MESSAGE_ID_WRITE_AN,47	MOD_HDCP_MESSAGE_ID_READ_VH_X,48	MOD_HDCP_MESSAGE_ID_READ_VH_0,49	MOD_HDCP_MESSAGE_ID_READ_VH_1,50	MOD_HDCP_MESSAGE_ID_READ_VH_2,51	MOD_HDCP_MESSAGE_ID_READ_VH_3,52	MOD_HDCP_MESSAGE_ID_READ_VH_4,53	MOD_HDCP_MESSAGE_ID_READ_BCAPS,54	MOD_HDCP_MESSAGE_ID_READ_BSTATUS,55	MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO,56	MOD_HDCP_MESSAGE_ID_READ_BINFO,57 58	/* HDCP 2.2 */59 60	MOD_HDCP_MESSAGE_ID_HDCP2VERSION,61	MOD_HDCP_MESSAGE_ID_RX_CAPS,62	MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT,63	MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT,64	MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM,65	MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM,66	MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME,67	MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO,68	MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT,69	MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME,70	MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS,71	MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST,72	MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2,73	MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK,74	MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE,75	MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY,76	MOD_HDCP_MESSAGE_ID_READ_RXSTATUS,77	MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE,78 79	MOD_HDCP_MESSAGE_ID_MAX80};81 82static const uint8_t hdcp_i2c_offsets[] = {83	[MOD_HDCP_MESSAGE_ID_READ_BKSV] = 0x0,84	[MOD_HDCP_MESSAGE_ID_READ_RI_R0] = 0x8,85	[MOD_HDCP_MESSAGE_ID_WRITE_AKSV] = 0x10,86	[MOD_HDCP_MESSAGE_ID_WRITE_AINFO] = 0x15,87	[MOD_HDCP_MESSAGE_ID_WRITE_AN] = 0x18,88	[MOD_HDCP_MESSAGE_ID_READ_VH_X] = 0x20,89	[MOD_HDCP_MESSAGE_ID_READ_VH_0] = 0x20,90	[MOD_HDCP_MESSAGE_ID_READ_VH_1] = 0x24,91	[MOD_HDCP_MESSAGE_ID_READ_VH_2] = 0x28,92	[MOD_HDCP_MESSAGE_ID_READ_VH_3] = 0x2C,93	[MOD_HDCP_MESSAGE_ID_READ_VH_4] = 0x30,94	[MOD_HDCP_MESSAGE_ID_READ_BCAPS] = 0x40,95	[MOD_HDCP_MESSAGE_ID_READ_BSTATUS] = 0x41,96	[MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO] = 0x43,97	[MOD_HDCP_MESSAGE_ID_READ_BINFO] = 0xFF,98	[MOD_HDCP_MESSAGE_ID_HDCP2VERSION] = 0x50,99	[MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT] = 0x60,100	[MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT] = 0x80,101	[MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM] = 0x60,102	[MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM] = 0x60,103	[MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME] = 0x80,104	[MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO] = 0x80,105	[MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT] = 0x60,106	[MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = 0x80,107	[MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = 0x60,108	[MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = 0x80,109	[MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2] = 0x80,110	[MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = 0x60,111	[MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = 0x60,112	[MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = 0x80,113	[MOD_HDCP_MESSAGE_ID_READ_RXSTATUS] = 0x70,114	[MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = 0x0115};116 117static const uint32_t hdcp_dpcd_addrs[] = {118	[MOD_HDCP_MESSAGE_ID_READ_BKSV] = 0x68000,119	[MOD_HDCP_MESSAGE_ID_READ_RI_R0] = 0x68005,120	[MOD_HDCP_MESSAGE_ID_WRITE_AKSV] = 0x68007,121	[MOD_HDCP_MESSAGE_ID_WRITE_AINFO] = 0x6803B,122	[MOD_HDCP_MESSAGE_ID_WRITE_AN] = 0x6800c,123	[MOD_HDCP_MESSAGE_ID_READ_VH_X] = 0x68014,124	[MOD_HDCP_MESSAGE_ID_READ_VH_0] = 0x68014,125	[MOD_HDCP_MESSAGE_ID_READ_VH_1] = 0x68018,126	[MOD_HDCP_MESSAGE_ID_READ_VH_2] = 0x6801c,127	[MOD_HDCP_MESSAGE_ID_READ_VH_3] = 0x68020,128	[MOD_HDCP_MESSAGE_ID_READ_VH_4] = 0x68024,129	[MOD_HDCP_MESSAGE_ID_READ_BCAPS] = 0x68028,130	[MOD_HDCP_MESSAGE_ID_READ_BSTATUS] = 0x68029,131	[MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO] = 0x6802c,132	[MOD_HDCP_MESSAGE_ID_READ_BINFO] = 0x6802a,133	[MOD_HDCP_MESSAGE_ID_RX_CAPS] = 0x6921d,134	[MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT] = 0x69000,135	[MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT] = 0x6900b,136	[MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM] = 0x69220,137	[MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM] = 0x692a0,138	[MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME] = 0x692c0,139	[MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO] = 0x692e0,140	[MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT] = 0x692f0,141	[MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = 0x692f8,142	[MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = 0x69318,143	[MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = 0x69330,144	[MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2] = 0x69340,145	[MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = 0x693e0,146	[MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = 0x693f0,147	[MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = 0x69473,148	[MOD_HDCP_MESSAGE_ID_READ_RXSTATUS] = 0x69493,149	[MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = 0x69494150};151 152static enum mod_hdcp_status read(struct mod_hdcp *hdcp,153		enum mod_hdcp_ddc_message_id msg_id,154		uint8_t *buf,155		uint32_t buf_len)156{157	bool success = true;158	uint32_t cur_size = 0;159	uint32_t data_offset = 0;160 161	if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID ||162		msg_id >= MOD_HDCP_MESSAGE_ID_MAX)163		return MOD_HDCP_STATUS_DDC_FAILURE;164 165	if (is_dp_hdcp(hdcp)) {166		int num_dpcd_addrs = ARRAY_SIZE(hdcp_dpcd_addrs);167		if (msg_id >= num_dpcd_addrs)168			return MOD_HDCP_STATUS_DDC_FAILURE;169 170		while (buf_len > 0) {171			cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE);172			success = hdcp->config.ddc.funcs.read_dpcd(hdcp->config.ddc.handle,173					hdcp_dpcd_addrs[msg_id] + data_offset,174					buf + data_offset,175					cur_size);176 177			if (!success)178				break;179 180			buf_len -= cur_size;181			data_offset += cur_size;182		}183	} else {184		int num_i2c_offsets = ARRAY_SIZE(hdcp_i2c_offsets);185		if (msg_id >= num_i2c_offsets)186			return MOD_HDCP_STATUS_DDC_FAILURE;187 188		success = hdcp->config.ddc.funcs.read_i2c(189				hdcp->config.ddc.handle,190				HDCP_I2C_ADDR,191				hdcp_i2c_offsets[msg_id],192				buf,193				(uint32_t)buf_len);194	}195 196	return success ? MOD_HDCP_STATUS_SUCCESS : MOD_HDCP_STATUS_DDC_FAILURE;197}198 199static enum mod_hdcp_status read_repeatedly(struct mod_hdcp *hdcp,200		enum mod_hdcp_ddc_message_id msg_id,201		uint8_t *buf,202		uint32_t buf_len,203		uint8_t read_size)204{205	enum mod_hdcp_status status = MOD_HDCP_STATUS_DDC_FAILURE;206	uint32_t cur_size = 0;207	uint32_t data_offset = 0;208 209	while (buf_len > 0) {210		cur_size = MIN(buf_len, read_size);211		status = read(hdcp, msg_id, buf + data_offset, cur_size);212 213		if (status != MOD_HDCP_STATUS_SUCCESS)214			break;215 216		buf_len -= cur_size;217		data_offset += cur_size;218	}219 220	return status;221}222 223static enum mod_hdcp_status write(struct mod_hdcp *hdcp,224		enum mod_hdcp_ddc_message_id msg_id,225		uint8_t *buf,226		uint32_t buf_len)227{228	bool success = true;229	uint32_t cur_size = 0;230	uint32_t data_offset = 0;231 232	if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID ||233		msg_id >= MOD_HDCP_MESSAGE_ID_MAX)234		return MOD_HDCP_STATUS_DDC_FAILURE;235 236	if (is_dp_hdcp(hdcp)) {237		int num_dpcd_addrs = ARRAY_SIZE(hdcp_dpcd_addrs);238		if (msg_id >= num_dpcd_addrs)239			return MOD_HDCP_STATUS_DDC_FAILURE;240 241		while (buf_len > 0) {242			cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE);243			success = hdcp->config.ddc.funcs.write_dpcd(244					hdcp->config.ddc.handle,245					hdcp_dpcd_addrs[msg_id] + data_offset,246					buf + data_offset,247					cur_size);248 249			if (!success)250				break;251 252			buf_len -= cur_size;253			data_offset += cur_size;254		}255	} else {256		int num_i2c_offsets = ARRAY_SIZE(hdcp_i2c_offsets);257		if (msg_id >= num_i2c_offsets)258			return MOD_HDCP_STATUS_DDC_FAILURE;259 260		hdcp->buf[0] = hdcp_i2c_offsets[msg_id];261		memmove(&hdcp->buf[1], buf, buf_len);262		success = hdcp->config.ddc.funcs.write_i2c(263				hdcp->config.ddc.handle,264				HDCP_I2C_ADDR,265				hdcp->buf,266				(uint32_t)(buf_len+1));267	}268 269	return success ? MOD_HDCP_STATUS_SUCCESS : MOD_HDCP_STATUS_DDC_FAILURE;270}271 272enum mod_hdcp_status mod_hdcp_read_bksv(struct mod_hdcp *hdcp)273{274	return read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BKSV,275			hdcp->auth.msg.hdcp1.bksv,276			sizeof(hdcp->auth.msg.hdcp1.bksv));277}278 279enum mod_hdcp_status mod_hdcp_read_bcaps(struct mod_hdcp *hdcp)280{281	return read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BCAPS,282			&hdcp->auth.msg.hdcp1.bcaps,283			sizeof(hdcp->auth.msg.hdcp1.bcaps));284}285 286enum mod_hdcp_status mod_hdcp_read_bstatus(struct mod_hdcp *hdcp)287{288	enum mod_hdcp_status status;289 290	if (is_dp_hdcp(hdcp))291		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BSTATUS,292					(uint8_t *)&hdcp->auth.msg.hdcp1.bstatus,293					1);294	else295		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BSTATUS,296				(uint8_t *)&hdcp->auth.msg.hdcp1.bstatus,297				sizeof(hdcp->auth.msg.hdcp1.bstatus));298	return status;299}300 301enum mod_hdcp_status mod_hdcp_read_r0p(struct mod_hdcp *hdcp)302{303	return read(hdcp, MOD_HDCP_MESSAGE_ID_READ_RI_R0,304			(uint8_t *)&hdcp->auth.msg.hdcp1.r0p,305			sizeof(hdcp->auth.msg.hdcp1.r0p));306}307 308/* special case, reading repeatedly at the same address, don't use read() */309enum mod_hdcp_status mod_hdcp_read_ksvlist(struct mod_hdcp *hdcp)310{311	enum mod_hdcp_status status;312 313	if (is_dp_hdcp(hdcp))314		status = read_repeatedly(hdcp, MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO,315				hdcp->auth.msg.hdcp1.ksvlist,316				hdcp->auth.msg.hdcp1.ksvlist_size,317				KSV_READ_SIZE);318	else319		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO,320				(uint8_t *)&hdcp->auth.msg.hdcp1.ksvlist,321				hdcp->auth.msg.hdcp1.ksvlist_size);322	return status;323}324 325enum mod_hdcp_status mod_hdcp_read_vp(struct mod_hdcp *hdcp)326{327	enum mod_hdcp_status status;328 329	status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_0,330			&hdcp->auth.msg.hdcp1.vp[0], 4);331	if (status != MOD_HDCP_STATUS_SUCCESS)332		goto out;333 334	status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_1,335			&hdcp->auth.msg.hdcp1.vp[4], 4);336	if (status != MOD_HDCP_STATUS_SUCCESS)337		goto out;338 339	status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_2,340			&hdcp->auth.msg.hdcp1.vp[8], 4);341	if (status != MOD_HDCP_STATUS_SUCCESS)342		goto out;343 344	status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_3,345			&hdcp->auth.msg.hdcp1.vp[12], 4);346	if (status != MOD_HDCP_STATUS_SUCCESS)347		goto out;348 349	status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_4,350			&hdcp->auth.msg.hdcp1.vp[16], 4);351out:352	return status;353}354 355enum mod_hdcp_status mod_hdcp_read_binfo(struct mod_hdcp *hdcp)356{357	enum mod_hdcp_status status;358 359	if (is_dp_hdcp(hdcp))360		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BINFO,361				(uint8_t *)&hdcp->auth.msg.hdcp1.binfo_dp,362				sizeof(hdcp->auth.msg.hdcp1.binfo_dp));363	else364		status = MOD_HDCP_STATUS_INVALID_OPERATION;365 366	return status;367}368 369enum mod_hdcp_status mod_hdcp_write_aksv(struct mod_hdcp *hdcp)370{371	return write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKSV,372			hdcp->auth.msg.hdcp1.aksv,373			sizeof(hdcp->auth.msg.hdcp1.aksv));374}375 376enum mod_hdcp_status mod_hdcp_write_ainfo(struct mod_hdcp *hdcp)377{378	return write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AINFO,379			&hdcp->auth.msg.hdcp1.ainfo,380			sizeof(hdcp->auth.msg.hdcp1.ainfo));381}382 383enum mod_hdcp_status mod_hdcp_write_an(struct mod_hdcp *hdcp)384{385	return write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AN,386			hdcp->auth.msg.hdcp1.an,387			sizeof(hdcp->auth.msg.hdcp1.an));388}389 390enum mod_hdcp_status mod_hdcp_read_hdcp2version(struct mod_hdcp *hdcp)391{392	enum mod_hdcp_status status;393 394	if (is_dp_hdcp(hdcp))395		status = MOD_HDCP_STATUS_INVALID_OPERATION;396	else397		status = read(hdcp, MOD_HDCP_MESSAGE_ID_HDCP2VERSION,398				&hdcp->auth.msg.hdcp2.hdcp2version_hdmi,399				sizeof(hdcp->auth.msg.hdcp2.hdcp2version_hdmi));400 401	return status;402}403 404enum mod_hdcp_status mod_hdcp_read_rxcaps(struct mod_hdcp *hdcp)405{406	enum mod_hdcp_status status;407 408	if (!is_dp_hdcp(hdcp))409		status = MOD_HDCP_STATUS_INVALID_OPERATION;410	else411		status = read(hdcp, MOD_HDCP_MESSAGE_ID_RX_CAPS,412				hdcp->auth.msg.hdcp2.rxcaps_dp,413				sizeof(hdcp->auth.msg.hdcp2.rxcaps_dp));414 415	return status;416}417 418enum mod_hdcp_status mod_hdcp_read_rxstatus(struct mod_hdcp *hdcp)419{420	enum mod_hdcp_status status;421 422	if (is_dp_hdcp(hdcp)) {423		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_RXSTATUS,424				&hdcp->auth.msg.hdcp2.rxstatus_dp,425				1);426	} else {427		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_RXSTATUS,428					(uint8_t *)&hdcp->auth.msg.hdcp2.rxstatus,429					sizeof(hdcp->auth.msg.hdcp2.rxstatus));430	}431	return status;432}433 434enum mod_hdcp_status mod_hdcp_read_ake_cert(struct mod_hdcp *hdcp)435{436	enum mod_hdcp_status status;437 438	if (is_dp_hdcp(hdcp)) {439		hdcp->auth.msg.hdcp2.ake_cert[0] = HDCP_2_2_AKE_SEND_CERT;440		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT,441				hdcp->auth.msg.hdcp2.ake_cert+1,442				sizeof(hdcp->auth.msg.hdcp2.ake_cert)-1);443 444	} else {445		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT,446					hdcp->auth.msg.hdcp2.ake_cert,447					sizeof(hdcp->auth.msg.hdcp2.ake_cert));448	}449	return status;450}451 452enum mod_hdcp_status mod_hdcp_read_h_prime(struct mod_hdcp *hdcp)453{454	enum mod_hdcp_status status;455 456	if (is_dp_hdcp(hdcp)) {457		hdcp->auth.msg.hdcp2.ake_h_prime[0] = HDCP_2_2_AKE_SEND_HPRIME;458		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME,459				hdcp->auth.msg.hdcp2.ake_h_prime+1,460				sizeof(hdcp->auth.msg.hdcp2.ake_h_prime)-1);461 462	} else {463		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME,464				hdcp->auth.msg.hdcp2.ake_h_prime,465				sizeof(hdcp->auth.msg.hdcp2.ake_h_prime));466	}467	return status;468}469 470enum mod_hdcp_status mod_hdcp_read_pairing_info(struct mod_hdcp *hdcp)471{472	enum mod_hdcp_status status;473 474	if (is_dp_hdcp(hdcp)) {475		hdcp->auth.msg.hdcp2.ake_pairing_info[0] = HDCP_2_2_AKE_SEND_PAIRING_INFO;476		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO,477				hdcp->auth.msg.hdcp2.ake_pairing_info+1,478				sizeof(hdcp->auth.msg.hdcp2.ake_pairing_info)-1);479 480	} else {481		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO,482				hdcp->auth.msg.hdcp2.ake_pairing_info,483				sizeof(hdcp->auth.msg.hdcp2.ake_pairing_info));484	}485	return status;486}487 488enum mod_hdcp_status mod_hdcp_read_l_prime(struct mod_hdcp *hdcp)489{490	enum mod_hdcp_status status;491 492	if (is_dp_hdcp(hdcp)) {493		hdcp->auth.msg.hdcp2.lc_l_prime[0] = HDCP_2_2_LC_SEND_LPRIME;494		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME,495				hdcp->auth.msg.hdcp2.lc_l_prime+1,496				sizeof(hdcp->auth.msg.hdcp2.lc_l_prime)-1);497 498	} else {499		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME,500				hdcp->auth.msg.hdcp2.lc_l_prime,501				sizeof(hdcp->auth.msg.hdcp2.lc_l_prime));502	}503	return status;504}505 506enum mod_hdcp_status mod_hdcp_read_rx_id_list(struct mod_hdcp *hdcp)507{508	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;509 510	if (is_dp_hdcp(hdcp)) {511		uint32_t device_count = 0;512		uint32_t rx_id_list_size = 0;513		uint32_t bytes_read = 0;514 515		hdcp->auth.msg.hdcp2.rx_id_list[0] = HDCP_2_2_REP_SEND_RECVID_LIST;516		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST,517						hdcp->auth.msg.hdcp2.rx_id_list+1,518						HDCP_MAX_AUX_TRANSACTION_SIZE);519		if (status == MOD_HDCP_STATUS_SUCCESS) {520			bytes_read = HDCP_MAX_AUX_TRANSACTION_SIZE;521			device_count = HDCP_2_2_DEV_COUNT_LO(hdcp->auth.msg.hdcp2.rx_id_list[2]) +522					(HDCP_2_2_DEV_COUNT_HI(hdcp->auth.msg.hdcp2.rx_id_list[1]) << 4);523			rx_id_list_size = MIN((21 + 5 * device_count),524					(sizeof(hdcp->auth.msg.hdcp2.rx_id_list) - 1));525			status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2,526					hdcp->auth.msg.hdcp2.rx_id_list + 1 + bytes_read,527					(rx_id_list_size - 1) / HDCP_MAX_AUX_TRANSACTION_SIZE * HDCP_MAX_AUX_TRANSACTION_SIZE);528		}529	} else {530		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST,531				hdcp->auth.msg.hdcp2.rx_id_list,532				hdcp->auth.msg.hdcp2.rx_id_list_size);533	}534	return status;535}536 537enum mod_hdcp_status mod_hdcp_read_stream_ready(struct mod_hdcp *hdcp)538{539	enum mod_hdcp_status status;540 541	if (is_dp_hdcp(hdcp)) {542		hdcp->auth.msg.hdcp2.repeater_auth_stream_ready[0] = HDCP_2_2_REP_STREAM_READY;543		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY,544				hdcp->auth.msg.hdcp2.repeater_auth_stream_ready+1,545				sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready)-1);546 547	} else {548		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY,549				hdcp->auth.msg.hdcp2.repeater_auth_stream_ready,550				sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready));551	}552	return status;553}554 555enum mod_hdcp_status mod_hdcp_write_ake_init(struct mod_hdcp *hdcp)556{557	enum mod_hdcp_status status;558 559	if (is_dp_hdcp(hdcp))560		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT,561				hdcp->auth.msg.hdcp2.ake_init+1,562				sizeof(hdcp->auth.msg.hdcp2.ake_init)-1);563	else564		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT,565					hdcp->auth.msg.hdcp2.ake_init,566					sizeof(hdcp->auth.msg.hdcp2.ake_init));567	return status;568}569 570enum mod_hdcp_status mod_hdcp_write_no_stored_km(struct mod_hdcp *hdcp)571{572	enum mod_hdcp_status status;573 574	if (is_dp_hdcp(hdcp))575		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM,576				hdcp->auth.msg.hdcp2.ake_no_stored_km+1,577				sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km)-1);578	else579		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM,580			hdcp->auth.msg.hdcp2.ake_no_stored_km,581			sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km));582	return status;583}584 585enum mod_hdcp_status mod_hdcp_write_stored_km(struct mod_hdcp *hdcp)586{587	enum mod_hdcp_status status;588 589	if (is_dp_hdcp(hdcp))590		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM,591				hdcp->auth.msg.hdcp2.ake_stored_km+1,592				sizeof(hdcp->auth.msg.hdcp2.ake_stored_km)-1);593	else594		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM,595				hdcp->auth.msg.hdcp2.ake_stored_km,596				sizeof(hdcp->auth.msg.hdcp2.ake_stored_km));597	return status;598}599 600enum mod_hdcp_status mod_hdcp_write_lc_init(struct mod_hdcp *hdcp)601{602	enum mod_hdcp_status status;603 604	if (is_dp_hdcp(hdcp))605		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT,606				hdcp->auth.msg.hdcp2.lc_init+1,607				sizeof(hdcp->auth.msg.hdcp2.lc_init)-1);608	else609		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT,610				hdcp->auth.msg.hdcp2.lc_init,611				sizeof(hdcp->auth.msg.hdcp2.lc_init));612	return status;613}614 615enum mod_hdcp_status mod_hdcp_write_eks(struct mod_hdcp *hdcp)616{617	enum mod_hdcp_status status;618 619	if (is_dp_hdcp(hdcp))620		status = write(hdcp,621				MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS,622				hdcp->auth.msg.hdcp2.ske_eks+1,623				sizeof(hdcp->auth.msg.hdcp2.ske_eks)-1);624	else625		status = write(hdcp,626			MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS,627			hdcp->auth.msg.hdcp2.ske_eks,628			sizeof(hdcp->auth.msg.hdcp2.ske_eks));629	return status;630}631 632enum mod_hdcp_status mod_hdcp_write_repeater_auth_ack(struct mod_hdcp *hdcp)633{634	enum mod_hdcp_status status;635 636	if (is_dp_hdcp(hdcp))637		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK,638				hdcp->auth.msg.hdcp2.repeater_auth_ack+1,639				sizeof(hdcp->auth.msg.hdcp2.repeater_auth_ack)-1);640	else641		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK,642				hdcp->auth.msg.hdcp2.repeater_auth_ack,643				sizeof(hdcp->auth.msg.hdcp2.repeater_auth_ack));644	return status;645}646 647enum mod_hdcp_status mod_hdcp_write_stream_manage(struct mod_hdcp *hdcp)648{649	enum mod_hdcp_status status;650 651	if (is_dp_hdcp(hdcp))652		status = write(hdcp,653				MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE,654				hdcp->auth.msg.hdcp2.repeater_auth_stream_manage+1,655				hdcp->auth.msg.hdcp2.stream_manage_size-1);656	else657		status = write(hdcp,658				MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE,659				hdcp->auth.msg.hdcp2.repeater_auth_stream_manage,660				hdcp->auth.msg.hdcp2.stream_manage_size);661	return status;662}663 664enum mod_hdcp_status mod_hdcp_write_content_type(struct mod_hdcp *hdcp)665{666	enum mod_hdcp_status status;667 668	if (is_dp_hdcp(hdcp))669		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE,670				hdcp->auth.msg.hdcp2.content_stream_type_dp+1,671				sizeof(hdcp->auth.msg.hdcp2.content_stream_type_dp)-1);672	else673		status = MOD_HDCP_STATUS_INVALID_OPERATION;674	return status;675}676 677enum mod_hdcp_status mod_hdcp_clear_cp_irq_status(struct mod_hdcp *hdcp)678{679	uint8_t clear_cp_irq_bit = DP_CP_IRQ;680	uint32_t size = 1;681 682	if (is_dp_hdcp(hdcp)) {683		uint32_t cp_irq_addrs = (hdcp->connection.link.dp.rev >= 0x14)684				? DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0:DP_DEVICE_SERVICE_IRQ_VECTOR;685		return hdcp->config.ddc.funcs.write_dpcd(hdcp->config.ddc.handle, cp_irq_addrs,686				&clear_cp_irq_bit, size) ? MOD_HDCP_STATUS_SUCCESS : MOD_HDCP_STATUS_DDC_FAILURE;687	}688 689	return MOD_HDCP_STATUS_INVALID_OPERATION;690}691