1/*
2 * Copyright 2018 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * 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 OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: AMD
23 *
24 */
25
26#define MAX_NUM_DISPLAYS 24
27
28
29#include "hdcp.h"
30
31#include "amdgpu.h"
32#include "hdcp_psp.h"
33
34static void hdcp2_message_init(struct mod_hdcp *hdcp,
35			       struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *in)
36{
37	in->session_handle = hdcp->auth.id;
38	in->prepare.msg1_id = TA_HDCP_HDCP2_MSG_ID__NULL_MESSAGE;
39	in->prepare.msg2_id = TA_HDCP_HDCP2_MSG_ID__NULL_MESSAGE;
40	in->process.msg1_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__NULL_MESSAGE;
41	in->process.msg1_desc.msg_size = 0;
42	in->process.msg2_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__NULL_MESSAGE;
43	in->process.msg2_desc.msg_size = 0;
44	in->process.msg3_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__NULL_MESSAGE;
45	in->process.msg3_desc.msg_size = 0;
46}
47
48static enum mod_hdcp_status remove_display_from_topology_v2(
49		struct mod_hdcp *hdcp, uint8_t index)
50{
51	struct psp_context *psp = hdcp->config.psp.handle;
52	struct ta_dtm_shared_memory *dtm_cmd;
53	struct mod_hdcp_display *display =
54			get_active_display_at_index(hdcp, index);
55	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
56
57	dtm_cmd = (struct ta_dtm_shared_memory *)psp->dtm_context.context.mem_context.shared_buf;
58
59	if (!display || !is_display_active(display))
60		return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND;
61
62	mutex_lock(&psp->dtm_context.mutex);
63
64	memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory));
65
66	dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_UPDATE_V2;
67	dtm_cmd->dtm_in_message.topology_update_v2.display_handle = display->index;
68	dtm_cmd->dtm_in_message.topology_update_v2.is_active = 0;
69	dtm_cmd->dtm_status = TA_DTM_STATUS__GENERIC_FAILURE;
70
71	psp_dtm_invoke(psp, dtm_cmd->cmd_id);
72
73	if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) {
74		status = MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE;
75	} else {
76		display->state = MOD_HDCP_DISPLAY_ACTIVE;
77		HDCP_TOP_REMOVE_DISPLAY_TRACE(hdcp, display->index);
78	}
79
80	mutex_unlock(&psp->dtm_context.mutex);
81	return status;
82}
83
84static enum mod_hdcp_status remove_display_from_topology_v3(
85		struct mod_hdcp *hdcp, uint8_t index)
86{
87	struct psp_context *psp = hdcp->config.psp.handle;
88	struct ta_dtm_shared_memory *dtm_cmd;
89	struct mod_hdcp_display *display =
90		get_active_display_at_index(hdcp, index);
91	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
92
93	dtm_cmd = (struct ta_dtm_shared_memory *)psp->dtm_context.context.mem_context.shared_buf;
94
95	if (!display || !is_display_active(display))
96		return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND;
97
98	mutex_lock(&psp->dtm_context.mutex);
99
100	memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory));
101
102	dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_UPDATE_V3;
103	dtm_cmd->dtm_in_message.topology_update_v3.display_handle = display->index;
104	dtm_cmd->dtm_in_message.topology_update_v3.is_active = 0;
105	dtm_cmd->dtm_status = TA_DTM_STATUS__GENERIC_FAILURE;
106
107	psp_dtm_invoke(psp, dtm_cmd->cmd_id);
108	mutex_unlock(&psp->dtm_context.mutex);
109
110	if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) {
111		status = remove_display_from_topology_v2(hdcp, index);
112		if (status != MOD_HDCP_STATUS_SUCCESS)
113			display->state = MOD_HDCP_DISPLAY_INACTIVE;
114	} else {
115		display->state = MOD_HDCP_DISPLAY_ACTIVE;
116		HDCP_TOP_REMOVE_DISPLAY_TRACE(hdcp, display->index);
117	}
118
119	return status;
120}
121
122static enum mod_hdcp_status add_display_to_topology_v2(
123		struct mod_hdcp *hdcp, struct mod_hdcp_display *display)
124{
125	struct psp_context *psp = hdcp->config.psp.handle;
126	struct ta_dtm_shared_memory *dtm_cmd;
127	struct mod_hdcp_link *link = &hdcp->connection.link;
128	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
129
130	if (!psp->dtm_context.context.initialized) {
131		DRM_INFO("Failed to add display topology, DTM TA is not initialized.");
132		display->state = MOD_HDCP_DISPLAY_INACTIVE;
133		return MOD_HDCP_STATUS_FAILURE;
134	}
135
136	dtm_cmd = (struct ta_dtm_shared_memory *)psp->dtm_context.context.mem_context.shared_buf;
137
138	mutex_lock(&psp->dtm_context.mutex);
139	memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory));
140
141	dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_UPDATE_V2;
142	dtm_cmd->dtm_in_message.topology_update_v2.display_handle = display->index;
143	dtm_cmd->dtm_in_message.topology_update_v2.is_active = 1;
144	dtm_cmd->dtm_in_message.topology_update_v2.controller = display->controller;
145	dtm_cmd->dtm_in_message.topology_update_v2.ddc_line = link->ddc_line;
146	dtm_cmd->dtm_in_message.topology_update_v2.dig_be = link->dig_be;
147	dtm_cmd->dtm_in_message.topology_update_v2.dig_fe = display->dig_fe;
148	if (is_dp_hdcp(hdcp))
149		dtm_cmd->dtm_in_message.topology_update_v2.is_assr = link->dp.assr_enabled;
150
151	dtm_cmd->dtm_in_message.topology_update_v2.dp_mst_vcid = display->vc_id;
152	dtm_cmd->dtm_in_message.topology_update_v2.max_hdcp_supported_version =
153			TA_DTM_HDCP_VERSION_MAX_SUPPORTED__2_2;
154	dtm_cmd->dtm_status = TA_DTM_STATUS__GENERIC_FAILURE;
155
156	psp_dtm_invoke(psp, dtm_cmd->cmd_id);
157
158	if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) {
159		display->state = MOD_HDCP_DISPLAY_INACTIVE;
160		status = MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE;
161	} else {
162		HDCP_TOP_ADD_DISPLAY_TRACE(hdcp, display->index);
163	}
164
165	mutex_unlock(&psp->dtm_context.mutex);
166	return status;
167}
168
169static enum mod_hdcp_status add_display_to_topology_v3(
170		struct mod_hdcp *hdcp, struct mod_hdcp_display *display)
171{
172	struct psp_context *psp = hdcp->config.psp.handle;
173	struct ta_dtm_shared_memory *dtm_cmd;
174	struct mod_hdcp_link *link = &hdcp->connection.link;
175	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
176
177	if (!psp->dtm_context.context.initialized) {
178		DRM_INFO("Failed to add display topology, DTM TA is not initialized.");
179		display->state = MOD_HDCP_DISPLAY_INACTIVE;
180		return MOD_HDCP_STATUS_FAILURE;
181	}
182
183	dtm_cmd = (struct ta_dtm_shared_memory *)psp->dtm_context.context.mem_context.shared_buf;
184
185	mutex_lock(&psp->dtm_context.mutex);
186	memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory));
187
188	dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_UPDATE_V3;
189	dtm_cmd->dtm_in_message.topology_update_v3.display_handle = display->index;
190	dtm_cmd->dtm_in_message.topology_update_v3.is_active = 1;
191	dtm_cmd->dtm_in_message.topology_update_v3.controller = display->controller;
192	dtm_cmd->dtm_in_message.topology_update_v3.ddc_line = link->ddc_line;
193	dtm_cmd->dtm_in_message.topology_update_v3.link_enc = link->link_enc_idx;
194	dtm_cmd->dtm_in_message.topology_update_v3.stream_enc = display->stream_enc_idx;
195	if (is_dp_hdcp(hdcp))
196		dtm_cmd->dtm_in_message.topology_update_v3.is_assr = link->dp.assr_enabled;
197
198	dtm_cmd->dtm_in_message.topology_update_v3.dp_mst_vcid = display->vc_id;
199	dtm_cmd->dtm_in_message.topology_update_v3.max_hdcp_supported_version =
200			TA_DTM_HDCP_VERSION_MAX_SUPPORTED__2_3;
201	dtm_cmd->dtm_in_message.topology_update_v3.encoder_type = TA_DTM_ENCODER_TYPE__DIG;
202	dtm_cmd->dtm_status = TA_DTM_STATUS__GENERIC_FAILURE;
203	dtm_cmd->dtm_in_message.topology_update_v3.phy_id = link->phy_idx;
204	dtm_cmd->dtm_in_message.topology_update_v3.link_hdcp_cap = link->hdcp_supported_informational;
205	dtm_cmd->dtm_in_message.topology_update_v3.dio_output_type = link->dp.usb4_enabled ?
206			TA_DTM_DIO_OUTPUT_TYPE__DPIA :
207			TA_DTM_DIO_OUTPUT_TYPE__DIRECT;
208	dtm_cmd->dtm_in_message.topology_update_v3.dio_output_id = link->dio_output_id;
209
210	psp_dtm_invoke(psp, dtm_cmd->cmd_id);
211	mutex_unlock(&psp->dtm_context.mutex);
212
213	if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) {
214		status = add_display_to_topology_v2(hdcp, display);
215		if (status != MOD_HDCP_STATUS_SUCCESS)
216			display->state = MOD_HDCP_DISPLAY_INACTIVE;
217	} else {
218		HDCP_TOP_ADD_DISPLAY_TRACE(hdcp, display->index);
219	}
220
221	return status;
222}
223
224enum mod_hdcp_status mod_hdcp_remove_display_from_topology(
225		struct mod_hdcp *hdcp, uint8_t index)
226{
227	enum mod_hdcp_status status = MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE;
228
229	if (hdcp->config.psp.caps.dtm_v3_supported)
230		status = remove_display_from_topology_v3(hdcp, index);
231	else
232		status = remove_display_from_topology_v2(hdcp, index);
233
234	return status;
235}
236
237enum mod_hdcp_status mod_hdcp_add_display_to_topology(struct mod_hdcp *hdcp,
238					       struct mod_hdcp_display *display)
239{
240	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
241
242	if (hdcp->config.psp.caps.dtm_v3_supported)
243		status = add_display_to_topology_v3(hdcp, display);
244	else
245		status = add_display_to_topology_v2(hdcp, display);
246
247	return status;
248}
249
250enum mod_hdcp_status mod_hdcp_hdcp1_create_session(struct mod_hdcp *hdcp)
251{
252
253	struct psp_context *psp = hdcp->config.psp.handle;
254	struct mod_hdcp_display *display = get_first_active_display(hdcp);
255	struct ta_hdcp_shared_memory *hdcp_cmd;
256	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
257
258	if (!psp->hdcp_context.context.initialized) {
259		DRM_ERROR("Failed to create hdcp session. HDCP TA is not initialized.");
260		return MOD_HDCP_STATUS_FAILURE;
261	}
262
263	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;
264
265	mutex_lock(&psp->hdcp_context.mutex);
266	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
267
268	hdcp_cmd->in_msg.hdcp1_create_session.display_handle = display->index;
269	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP1_CREATE_SESSION;
270
271	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
272
273	hdcp->auth.id = hdcp_cmd->out_msg.hdcp1_create_session.session_handle;
274
275	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {
276		status = MOD_HDCP_STATUS_HDCP1_CREATE_SESSION_FAILURE;
277	} else {
278		hdcp->auth.msg.hdcp1.ainfo = hdcp_cmd->out_msg.hdcp1_create_session.ainfo_primary;
279		memcpy(hdcp->auth.msg.hdcp1.aksv, hdcp_cmd->out_msg.hdcp1_create_session.aksv_primary,
280		       sizeof(hdcp->auth.msg.hdcp1.aksv));
281		memcpy(hdcp->auth.msg.hdcp1.an, hdcp_cmd->out_msg.hdcp1_create_session.an_primary,
282		       sizeof(hdcp->auth.msg.hdcp1.an));
283	}
284
285	mutex_unlock(&psp->hdcp_context.mutex);
286	return status;
287}
288
289enum mod_hdcp_status mod_hdcp_hdcp1_destroy_session(struct mod_hdcp *hdcp)
290{
291
292	struct psp_context *psp = hdcp->config.psp.handle;
293	struct ta_hdcp_shared_memory *hdcp_cmd;
294	uint8_t i = 0;
295	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
296
297	mutex_lock(&psp->hdcp_context.mutex);
298	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;
299	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
300
301	hdcp_cmd->in_msg.hdcp1_destroy_session.session_handle = hdcp->auth.id;
302	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP1_DESTROY_SESSION;
303
304	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
305
306	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {
307		status = MOD_HDCP_STATUS_HDCP1_DESTROY_SESSION_FAILURE;
308	} else {
309		HDCP_TOP_HDCP1_DESTROY_SESSION_TRACE(hdcp);
310		for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++)
311			if (is_display_encryption_enabled(&hdcp->displays[i])) {
312				hdcp->displays[i].state =
313							MOD_HDCP_DISPLAY_ACTIVE;
314				HDCP_HDCP1_DISABLED_TRACE(
315					hdcp, hdcp->displays[i].index);
316			}
317	}
318
319	mutex_unlock(&psp->hdcp_context.mutex);
320	return status;
321}
322
323enum mod_hdcp_status mod_hdcp_hdcp1_validate_rx(struct mod_hdcp *hdcp)
324{
325	struct psp_context *psp = hdcp->config.psp.handle;
326	struct ta_hdcp_shared_memory *hdcp_cmd;
327	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
328
329	mutex_lock(&psp->hdcp_context.mutex);
330	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;
331	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
332
333	hdcp_cmd->in_msg.hdcp1_first_part_authentication.session_handle = hdcp->auth.id;
334
335	memcpy(hdcp_cmd->in_msg.hdcp1_first_part_authentication.bksv_primary, hdcp->auth.msg.hdcp1.bksv,
336		TA_HDCP__HDCP1_KSV_SIZE);
337
338	hdcp_cmd->in_msg.hdcp1_first_part_authentication.r0_prime_primary = hdcp->auth.msg.hdcp1.r0p;
339	hdcp_cmd->in_msg.hdcp1_first_part_authentication.bcaps = hdcp->auth.msg.hdcp1.bcaps;
340	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP1_FIRST_PART_AUTHENTICATION;
341
342	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
343
344	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {
345		status = MOD_HDCP_STATUS_HDCP1_VALIDATE_RX_FAILURE;
346	} else if (hdcp_cmd->out_msg.hdcp1_first_part_authentication.authentication_status ==
347	    TA_HDCP_AUTHENTICATION_STATUS__HDCP1_FIRST_PART_COMPLETE) {
348		/* needs second part of authentication */
349		hdcp->connection.is_repeater = 1;
350	} else if (hdcp_cmd->out_msg.hdcp1_first_part_authentication.authentication_status ==
351		   TA_HDCP_AUTHENTICATION_STATUS__HDCP1_AUTHENTICATED) {
352		hdcp->connection.is_repeater = 0;
353	} else if (hdcp_cmd->out_msg.hdcp1_first_part_authentication.authentication_status ==
354		   TA_HDCP_AUTHENTICATION_STATUS__HDCP1_KSV_REVOKED) {
355		hdcp->connection.is_hdcp1_revoked = 1;
356		status = MOD_HDCP_STATUS_HDCP1_BKSV_REVOKED;
357	} else
358		status = MOD_HDCP_STATUS_HDCP1_VALIDATE_RX_FAILURE;
359
360	mutex_unlock(&psp->hdcp_context.mutex);
361	return status;
362}
363
364enum mod_hdcp_status mod_hdcp_hdcp1_enable_encryption(struct mod_hdcp *hdcp)
365{
366	struct psp_context *psp = hdcp->config.psp.handle;
367	struct ta_hdcp_shared_memory *hdcp_cmd;
368	struct mod_hdcp_display *display = get_first_active_display(hdcp);
369	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
370
371	mutex_lock(&psp->hdcp_context.mutex);
372	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;
373	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
374
375	hdcp_cmd->in_msg.hdcp1_enable_encryption.session_handle = hdcp->auth.id;
376	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP1_ENABLE_ENCRYPTION;
377
378	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
379
380	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {
381		status = MOD_HDCP_STATUS_HDCP1_ENABLE_ENCRYPTION_FAILURE;
382	} else if (!is_dp_mst_hdcp(hdcp)) {
383		display->state = MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED;
384		HDCP_HDCP1_ENABLED_TRACE(hdcp, display->index);
385	}
386
387	mutex_unlock(&psp->hdcp_context.mutex);
388	return status;
389}
390
391enum mod_hdcp_status mod_hdcp_hdcp1_validate_ksvlist_vp(struct mod_hdcp *hdcp)
392{
393	struct psp_context *psp = hdcp->config.psp.handle;
394	struct ta_hdcp_shared_memory *hdcp_cmd;
395	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
396
397	mutex_lock(&psp->hdcp_context.mutex);
398	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;
399	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
400
401	hdcp_cmd->in_msg.hdcp1_second_part_authentication.session_handle = hdcp->auth.id;
402
403	hdcp_cmd->in_msg.hdcp1_second_part_authentication.ksv_list_size = hdcp->auth.msg.hdcp1.ksvlist_size;
404	memcpy(hdcp_cmd->in_msg.hdcp1_second_part_authentication.ksv_list, hdcp->auth.msg.hdcp1.ksvlist,
405	       hdcp->auth.msg.hdcp1.ksvlist_size);
406
407	memcpy(hdcp_cmd->in_msg.hdcp1_second_part_authentication.v_prime, hdcp->auth.msg.hdcp1.vp,
408	       sizeof(hdcp->auth.msg.hdcp1.vp));
409
410	hdcp_cmd->in_msg.hdcp1_second_part_authentication.bstatus_binfo =
411		is_dp_hdcp(hdcp) ? hdcp->auth.msg.hdcp1.binfo_dp : hdcp->auth.msg.hdcp1.bstatus;
412	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP1_SECOND_PART_AUTHENTICATION;
413
414	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
415
416	if (hdcp_cmd->hdcp_status == TA_HDCP_STATUS__SUCCESS &&
417	    hdcp_cmd->out_msg.hdcp1_second_part_authentication.authentication_status ==
418		    TA_HDCP_AUTHENTICATION_STATUS__HDCP1_AUTHENTICATED) {
419		status = MOD_HDCP_STATUS_SUCCESS;
420	} else if (hdcp_cmd->out_msg.hdcp1_second_part_authentication.authentication_status ==
421		   TA_HDCP_AUTHENTICATION_STATUS__HDCP1_KSV_REVOKED) {
422		hdcp->connection.is_hdcp1_revoked = 1;
423		status = MOD_HDCP_STATUS_HDCP1_KSV_LIST_REVOKED;
424	} else {
425		status = MOD_HDCP_STATUS_HDCP1_VALIDATE_KSV_LIST_FAILURE;
426	}
427
428	mutex_unlock(&psp->hdcp_context.mutex);
429	return status;
430}
431
432enum mod_hdcp_status mod_hdcp_hdcp1_enable_dp_stream_encryption(struct mod_hdcp *hdcp)
433{
434
435	struct psp_context *psp = hdcp->config.psp.handle;
436	struct ta_hdcp_shared_memory *hdcp_cmd;
437	int i = 0;
438	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
439
440	mutex_lock(&psp->hdcp_context.mutex);
441	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;
442
443	for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) {
444
445		if (hdcp->displays[i].adjust.disable || hdcp->displays[i].state != MOD_HDCP_DISPLAY_ACTIVE)
446			continue;
447
448		memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
449
450		hdcp_cmd->in_msg.hdcp1_enable_dp_stream_encryption.session_handle = hdcp->auth.id;
451		hdcp_cmd->in_msg.hdcp1_enable_dp_stream_encryption.display_handle = hdcp->displays[i].index;
452		hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP1_ENABLE_DP_STREAM_ENCRYPTION;
453
454		psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
455
456		if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {
457			status = MOD_HDCP_STATUS_HDCP1_ENABLE_STREAM_ENCRYPTION_FAILURE;
458			break;
459		}
460
461		hdcp->displays[i].state = MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED;
462		HDCP_HDCP1_ENABLED_TRACE(hdcp, hdcp->displays[i].index);
463	}
464
465	mutex_unlock(&psp->hdcp_context.mutex);
466	return status;
467}
468
469enum mod_hdcp_status mod_hdcp_hdcp1_link_maintenance(struct mod_hdcp *hdcp)
470{
471	struct psp_context *psp = hdcp->config.psp.handle;
472	struct ta_hdcp_shared_memory *hdcp_cmd;
473	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
474
475	mutex_lock(&psp->hdcp_context.mutex);
476	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;
477
478	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
479
480	hdcp_cmd->in_msg.hdcp1_get_encryption_status.session_handle = hdcp->auth.id;
481
482	hdcp_cmd->out_msg.hdcp1_get_encryption_status.protection_level = 0;
483	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP1_GET_ENCRYPTION_STATUS;
484
485	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
486
487	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS ||
488			hdcp_cmd->out_msg.hdcp1_get_encryption_status.protection_level != 1)
489		status = MOD_HDCP_STATUS_HDCP1_LINK_MAINTENANCE_FAILURE;
490
491	mutex_unlock(&psp->hdcp_context.mutex);
492	return status;
493}
494
495enum mod_hdcp_status mod_hdcp_hdcp2_create_session(struct mod_hdcp *hdcp)
496{
497	struct psp_context *psp = hdcp->config.psp.handle;
498	struct ta_hdcp_shared_memory *hdcp_cmd;
499	struct mod_hdcp_display *display = get_first_active_display(hdcp);
500	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
501
502
503	if (!psp->hdcp_context.context.initialized) {
504		DRM_ERROR("Failed to create hdcp session, HDCP TA is not initialized");
505		return MOD_HDCP_STATUS_FAILURE;
506	}
507
508	if (!display)
509		return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND;
510
511	mutex_lock(&psp->hdcp_context.mutex);
512
513	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;
514	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
515
516	if (!display)
517		return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND;
518
519	hdcp_cmd->in_msg.hdcp2_create_session_v2.display_handle = display->index;
520
521	if (hdcp->connection.link.adjust.hdcp2.force_type == MOD_HDCP_FORCE_TYPE_0)
522		hdcp_cmd->in_msg.hdcp2_create_session_v2.negotiate_content_type =
523			TA_HDCP2_CONTENT_TYPE_NEGOTIATION_TYPE__FORCE_TYPE0;
524	else if (hdcp->connection.link.adjust.hdcp2.force_type == MOD_HDCP_FORCE_TYPE_1)
525		hdcp_cmd->in_msg.hdcp2_create_session_v2.negotiate_content_type =
526			TA_HDCP2_CONTENT_TYPE_NEGOTIATION_TYPE__FORCE_TYPE1;
527	else if (hdcp->connection.link.adjust.hdcp2.force_type == MOD_HDCP_FORCE_TYPE_MAX)
528		hdcp_cmd->in_msg.hdcp2_create_session_v2.negotiate_content_type =
529			TA_HDCP2_CONTENT_TYPE_NEGOTIATION_TYPE__MAX_SUPPORTED;
530
531	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_CREATE_SESSION_V2;
532
533	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
534
535
536	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
537		status = MOD_HDCP_STATUS_HDCP2_CREATE_SESSION_FAILURE;
538	else
539		hdcp->auth.id = hdcp_cmd->out_msg.hdcp2_create_session_v2.session_handle;
540
541	mutex_unlock(&psp->hdcp_context.mutex);
542	return status;
543}
544
545enum mod_hdcp_status mod_hdcp_hdcp2_destroy_session(struct mod_hdcp *hdcp)
546{
547	struct psp_context *psp = hdcp->config.psp.handle;
548	struct ta_hdcp_shared_memory *hdcp_cmd;
549	uint8_t i = 0;
550	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
551
552	mutex_lock(&psp->hdcp_context.mutex);
553	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;
554	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
555
556	hdcp_cmd->in_msg.hdcp2_destroy_session.session_handle = hdcp->auth.id;
557	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_DESTROY_SESSION;
558
559	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
560
561	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {
562		status = MOD_HDCP_STATUS_HDCP2_DESTROY_SESSION_FAILURE;
563	} else {
564		HDCP_TOP_HDCP2_DESTROY_SESSION_TRACE(hdcp);
565		for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++)
566			if (is_display_encryption_enabled(&hdcp->displays[i])) {
567				hdcp->displays[i].state =
568							MOD_HDCP_DISPLAY_ACTIVE;
569				HDCP_HDCP2_DISABLED_TRACE(
570					hdcp, hdcp->displays[i].index);
571			}
572	}
573
574	mutex_unlock(&psp->hdcp_context.mutex);
575	return status;
576}
577
578enum mod_hdcp_status mod_hdcp_hdcp2_prepare_ake_init(struct mod_hdcp *hdcp)
579{
580	struct psp_context *psp = hdcp->config.psp.handle;
581	struct ta_hdcp_shared_memory *hdcp_cmd;
582	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;
583	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;
584	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
585
586	mutex_lock(&psp->hdcp_context.mutex);
587	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;
588	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
589
590	msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2;
591	msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2;
592
593	hdcp2_message_init(hdcp, msg_in);
594
595	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2;
596	msg_in->prepare.msg1_id = TA_HDCP_HDCP2_MSG_ID__AKE_INIT;
597
598	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
599
600	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
601		status = MOD_HDCP_STATUS_HDCP2_PREP_AKE_INIT_FAILURE;
602	else
603		memcpy(&hdcp->auth.msg.hdcp2.ake_init[0], &msg_out->prepare.transmitter_message[0],
604		       sizeof(hdcp->auth.msg.hdcp2.ake_init));
605
606	mutex_unlock(&psp->hdcp_context.mutex);
607	return status;
608}
609
610enum mod_hdcp_status mod_hdcp_hdcp2_validate_ake_cert(struct mod_hdcp *hdcp)
611{
612	struct psp_context *psp = hdcp->config.psp.handle;
613	struct ta_hdcp_shared_memory *hdcp_cmd;
614	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;
615	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;
616	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
617
618	mutex_lock(&psp->hdcp_context.mutex);
619	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;
620	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
621
622	msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2;
623	msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2;
624
625	hdcp2_message_init(hdcp, msg_in);
626
627	msg_in->process.msg1_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__AKE_SEND_CERT;
628	msg_in->process.msg1_desc.msg_size = TA_HDCP_HDCP2_MSG_ID_MAX_SIZE__AKE_SEND_CERT;
629
630	memcpy(&msg_in->process.receiver_message[0], hdcp->auth.msg.hdcp2.ake_cert,
631	       sizeof(hdcp->auth.msg.hdcp2.ake_cert));
632
633	msg_in->prepare.msg1_id = TA_HDCP_HDCP2_MSG_ID__AKE_NO_STORED_KM;
634	msg_in->prepare.msg2_id = TA_HDCP_HDCP2_MSG_ID__AKE_STORED_KM;
635
636	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2;
637
638	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
639
640	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {
641		status = MOD_HDCP_STATUS_HDCP2_VALIDATE_AKE_CERT_FAILURE;
642	} else {
643		memcpy(hdcp->auth.msg.hdcp2.ake_no_stored_km,
644		       &msg_out->prepare.transmitter_message[0],
645		       sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km));
646
647		memcpy(hdcp->auth.msg.hdcp2.ake_stored_km,
648		       &msg_out->prepare.transmitter_message[sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km)],
649		       sizeof(hdcp->auth.msg.hdcp2.ake_stored_km));
650
651		if (msg_out->process.msg1_status ==
652		    TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS) {
653			hdcp->connection.is_km_stored =
654				msg_out->process.is_km_stored ? 1 : 0;
655			hdcp->connection.is_repeater =
656				msg_out->process.is_repeater ? 1 : 0;
657			status = MOD_HDCP_STATUS_SUCCESS;
658		} else if (msg_out->process.msg1_status ==
659			   TA_HDCP2_MSG_AUTHENTICATION_STATUS__RECEIVERID_REVOKED) {
660			hdcp->connection.is_hdcp2_revoked = 1;
661			status = MOD_HDCP_STATUS_HDCP2_AKE_CERT_REVOKED;
662		}  else {
663			status = MOD_HDCP_STATUS_HDCP2_VALIDATE_AKE_CERT_FAILURE;
664		}
665	}
666	mutex_unlock(&psp->hdcp_context.mutex);
667	return status;
668}
669
670enum mod_hdcp_status mod_hdcp_hdcp2_validate_h_prime(struct mod_hdcp *hdcp)
671{
672	struct psp_context *psp = hdcp->config.psp.handle;
673	struct ta_hdcp_shared_memory *hdcp_cmd;
674	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;
675	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;
676	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
677
678	mutex_lock(&psp->hdcp_context.mutex);
679	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;
680	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
681
682	msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2;
683	msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2;
684
685	hdcp2_message_init(hdcp, msg_in);
686
687	msg_in->process.msg1_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__AKE_SEND_H_PRIME;
688	msg_in->process.msg1_desc.msg_size = TA_HDCP_HDCP2_MSG_ID_MAX_SIZE__AKE_SEND_H_PRIME;
689
690	memcpy(&msg_in->process.receiver_message[0], hdcp->auth.msg.hdcp2.ake_h_prime,
691	       sizeof(hdcp->auth.msg.hdcp2.ake_h_prime));
692
693	if (!hdcp->connection.is_km_stored) {
694		msg_in->process.msg2_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__AKE_SEND_PAIRING_INFO;
695		msg_in->process.msg2_desc.msg_size = TA_HDCP_HDCP2_MSG_ID_MAX_SIZE__AKE_SEND_PAIRING_INFO;
696		memcpy(&msg_in->process.receiver_message[sizeof(hdcp->auth.msg.hdcp2.ake_h_prime)],
697		       hdcp->auth.msg.hdcp2.ake_pairing_info, sizeof(hdcp->auth.msg.hdcp2.ake_pairing_info));
698	}
699
700	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2;
701
702	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
703
704	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
705		status = MOD_HDCP_STATUS_HDCP2_VALIDATE_H_PRIME_FAILURE;
706	else if (msg_out->process.msg1_status != TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS)
707		status = MOD_HDCP_STATUS_HDCP2_VALIDATE_H_PRIME_FAILURE;
708	else if (!hdcp->connection.is_km_stored &&
709		   msg_out->process.msg2_status != TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS)
710		status = MOD_HDCP_STATUS_HDCP2_VALIDATE_PAIRING_INFO_FAILURE;
711
712	mutex_unlock(&psp->hdcp_context.mutex);
713	return status;
714}
715
716enum mod_hdcp_status mod_hdcp_hdcp2_prepare_lc_init(struct mod_hdcp *hdcp)
717{
718	struct psp_context *psp = hdcp->config.psp.handle;
719	struct ta_hdcp_shared_memory *hdcp_cmd;
720	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;
721	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;
722	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
723
724	mutex_lock(&psp->hdcp_context.mutex);
725	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;
726	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
727
728	msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2;
729	msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2;
730
731	hdcp2_message_init(hdcp, msg_in);
732
733	msg_in->prepare.msg1_id = TA_HDCP_HDCP2_MSG_ID__LC_INIT;
734
735	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2;
736
737	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
738
739	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
740		status = MOD_HDCP_STATUS_HDCP2_PREP_LC_INIT_FAILURE;
741	else
742		memcpy(hdcp->auth.msg.hdcp2.lc_init, &msg_out->prepare.transmitter_message[0],
743		       sizeof(hdcp->auth.msg.hdcp2.lc_init));
744
745	mutex_unlock(&psp->hdcp_context.mutex);
746	return status;
747}
748
749enum mod_hdcp_status mod_hdcp_hdcp2_validate_l_prime(struct mod_hdcp *hdcp)
750{
751	struct psp_context *psp = hdcp->config.psp.handle;
752	struct ta_hdcp_shared_memory *hdcp_cmd;
753	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;
754	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;
755	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
756
757	mutex_lock(&psp->hdcp_context.mutex);
758	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;
759	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
760
761	msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2;
762	msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2;
763
764	hdcp2_message_init(hdcp, msg_in);
765
766	msg_in->process.msg1_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__LC_SEND_L_PRIME;
767	msg_in->process.msg1_desc.msg_size = TA_HDCP_HDCP2_MSG_ID_MAX_SIZE__LC_SEND_L_PRIME;
768
769	memcpy(&msg_in->process.receiver_message[0], hdcp->auth.msg.hdcp2.lc_l_prime,
770	       sizeof(hdcp->auth.msg.hdcp2.lc_l_prime));
771
772	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2;
773
774	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
775
776	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS ||
777			msg_out->process.msg1_status != TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS)
778		status = MOD_HDCP_STATUS_HDCP2_VALIDATE_L_PRIME_FAILURE;
779
780	mutex_unlock(&psp->hdcp_context.mutex);
781	return status;
782}
783
784enum mod_hdcp_status mod_hdcp_hdcp2_prepare_eks(struct mod_hdcp *hdcp)
785{
786	struct psp_context *psp = hdcp->config.psp.handle;
787	struct ta_hdcp_shared_memory *hdcp_cmd;
788	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;
789	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;
790	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
791
792	mutex_lock(&psp->hdcp_context.mutex);
793	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;
794	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
795
796	msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2;
797	msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2;
798
799	hdcp2_message_init(hdcp, msg_in);
800
801	msg_in->prepare.msg1_id = TA_HDCP_HDCP2_MSG_ID__SKE_SEND_EKS;
802
803	if (is_dp_hdcp(hdcp))
804		msg_in->prepare.msg2_id = TA_HDCP_HDCP2_MSG_ID__SIGNAL_CONTENT_STREAM_TYPE_DP;
805
806	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2;
807	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
808
809	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {
810		status = MOD_HDCP_STATUS_HDCP2_PREP_EKS_FAILURE;
811	} else {
812		memcpy(hdcp->auth.msg.hdcp2.ske_eks,
813		       &msg_out->prepare.transmitter_message[0],
814		       sizeof(hdcp->auth.msg.hdcp2.ske_eks));
815		msg_out->prepare.msg1_desc.msg_size =
816			sizeof(hdcp->auth.msg.hdcp2.ske_eks);
817
818		if (is_dp_hdcp(hdcp)) {
819			memcpy(hdcp->auth.msg.hdcp2.content_stream_type_dp,
820			       &msg_out->prepare.transmitter_message[sizeof(hdcp->auth.msg.hdcp2.ske_eks)],
821			       sizeof(hdcp->auth.msg.hdcp2.content_stream_type_dp));
822		}
823	}
824	mutex_unlock(&psp->hdcp_context.mutex);
825
826	return status;
827}
828
829enum mod_hdcp_status mod_hdcp_hdcp2_enable_encryption(struct mod_hdcp *hdcp)
830{
831	struct psp_context *psp = hdcp->config.psp.handle;
832	struct ta_hdcp_shared_memory *hdcp_cmd;
833	struct mod_hdcp_display *display = get_first_active_display(hdcp);
834	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
835
836	if (!display)
837		return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND;
838
839	mutex_lock(&psp->hdcp_context.mutex);
840
841	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;
842	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
843
844	hdcp_cmd->in_msg.hdcp2_set_encryption.session_handle = hdcp->auth.id;
845
846	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_SET_ENCRYPTION;
847	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
848
849	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {
850		status = MOD_HDCP_STATUS_HDCP2_ENABLE_ENCRYPTION_FAILURE;
851	} else if (!is_dp_mst_hdcp(hdcp)) {
852		display->state = MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED;
853		HDCP_HDCP2_ENABLED_TRACE(hdcp, display->index);
854	}
855
856	mutex_unlock(&psp->hdcp_context.mutex);
857	return status;
858}
859
860enum mod_hdcp_status mod_hdcp_hdcp2_validate_rx_id_list(struct mod_hdcp *hdcp)
861{
862	struct psp_context *psp = hdcp->config.psp.handle;
863	struct ta_hdcp_shared_memory *hdcp_cmd;
864	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;
865	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;
866	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
867
868	mutex_lock(&psp->hdcp_context.mutex);
869
870	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;
871	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
872
873	msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2;
874	msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2;
875
876	hdcp2_message_init(hdcp, msg_in);
877
878	msg_in->process.msg1_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__REPEATERAUTH_SEND_RECEIVERID_LIST;
879	msg_in->process.msg1_desc.msg_size = sizeof(hdcp->auth.msg.hdcp2.rx_id_list);
880	memcpy(&msg_in->process.receiver_message[0], hdcp->auth.msg.hdcp2.rx_id_list,
881	       sizeof(hdcp->auth.msg.hdcp2.rx_id_list));
882
883	msg_in->prepare.msg1_id = TA_HDCP_HDCP2_MSG_ID__REPEATERAUTH_SEND_ACK;
884
885	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2;
886
887	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
888
889	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {
890		status = MOD_HDCP_STATUS_HDCP2_VALIDATE_RX_ID_LIST_FAILURE;
891	} else {
892		memcpy(hdcp->auth.msg.hdcp2.repeater_auth_ack,
893		       &msg_out->prepare.transmitter_message[0],
894		       sizeof(hdcp->auth.msg.hdcp2.repeater_auth_ack));
895
896		if (msg_out->process.msg1_status ==
897		    TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS) {
898			hdcp->connection.is_km_stored = msg_out->process.is_km_stored ? 1 : 0;
899			hdcp->connection.is_repeater = msg_out->process.is_repeater ? 1 : 0;
900			status = MOD_HDCP_STATUS_SUCCESS;
901		} else if (msg_out->process.msg1_status ==
902			   TA_HDCP2_MSG_AUTHENTICATION_STATUS__RECEIVERID_REVOKED) {
903			hdcp->connection.is_hdcp2_revoked = 1;
904			status = MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_REVOKED;
905		} else {
906			status = MOD_HDCP_STATUS_HDCP2_VALIDATE_RX_ID_LIST_FAILURE;
907		}
908	}
909	mutex_unlock(&psp->hdcp_context.mutex);
910	return status;
911}
912
913enum mod_hdcp_status mod_hdcp_hdcp2_enable_dp_stream_encryption(struct mod_hdcp *hdcp)
914{
915	struct psp_context *psp = hdcp->config.psp.handle;
916	struct ta_hdcp_shared_memory *hdcp_cmd;
917	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;
918	uint8_t i;
919	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
920
921	mutex_lock(&psp->hdcp_context.mutex);
922	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;
923	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
924
925	msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2;
926
927	hdcp2_message_init(hdcp, msg_in);
928
929
930	for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) {
931		if (hdcp->displays[i].adjust.disable || hdcp->displays[i].state != MOD_HDCP_DISPLAY_ACTIVE)
932			continue;
933
934		hdcp_cmd->in_msg.hdcp2_enable_dp_stream_encryption.display_handle = hdcp->displays[i].index;
935		hdcp_cmd->in_msg.hdcp2_enable_dp_stream_encryption.session_handle = hdcp->auth.id;
936
937		hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_ENABLE_DP_STREAM_ENCRYPTION;
938		psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
939
940		if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)
941			break;
942
943		hdcp->displays[i].state = MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED;
944		HDCP_HDCP2_ENABLED_TRACE(hdcp, hdcp->displays[i].index);
945	}
946
947	if (hdcp_cmd->hdcp_status == TA_HDCP_STATUS__SUCCESS)
948		status = MOD_HDCP_STATUS_SUCCESS;
949	else
950		status = MOD_HDCP_STATUS_HDCP2_ENABLE_STREAM_ENCRYPTION_FAILURE;
951
952	mutex_unlock(&psp->hdcp_context.mutex);
953	return status;
954}
955
956enum mod_hdcp_status mod_hdcp_hdcp2_prepare_stream_management(struct mod_hdcp *hdcp)
957{
958
959	struct psp_context *psp = hdcp->config.psp.handle;
960	struct ta_hdcp_shared_memory *hdcp_cmd;
961	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;
962	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;
963	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
964
965	mutex_lock(&psp->hdcp_context.mutex);
966	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;
967	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
968
969	msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2;
970	msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2;
971
972	hdcp2_message_init(hdcp, msg_in);
973
974	msg_in->prepare.msg1_id = TA_HDCP_HDCP2_MSG_ID__REPEATERAUTH_STREAM_MANAGE;
975
976
977	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2;
978	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
979
980	if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {
981		status = MOD_HDCP_STATUS_HDCP2_PREPARE_STREAM_MANAGEMENT_FAILURE;
982	} else {
983		hdcp->auth.msg.hdcp2.stream_manage_size = msg_out->prepare.msg1_desc.msg_size;
984
985		memcpy(hdcp->auth.msg.hdcp2.repeater_auth_stream_manage,
986		       &msg_out->prepare.transmitter_message[0],
987		       sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_manage));
988	}
989	mutex_unlock(&psp->hdcp_context.mutex);
990	return status;
991}
992
993enum mod_hdcp_status mod_hdcp_hdcp2_validate_stream_ready(struct mod_hdcp *hdcp)
994{
995	struct psp_context *psp = hdcp->config.psp.handle;
996	struct ta_hdcp_shared_memory *hdcp_cmd;
997	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;
998	struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;
999	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
1000
1001	mutex_lock(&psp->hdcp_context.mutex);
1002	hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;
1003	memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
1004
1005	msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2;
1006	msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2;
1007
1008	hdcp2_message_init(hdcp, msg_in);
1009
1010	msg_in->process.msg1_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__REPEATERAUTH_STREAM_READY;
1011
1012	msg_in->process.msg1_desc.msg_size = sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready);
1013
1014	memcpy(&msg_in->process.receiver_message[0], hdcp->auth.msg.hdcp2.repeater_auth_stream_ready,
1015	       sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready));
1016
1017	hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2;
1018	psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);
1019
1020	if (hdcp_cmd->hdcp_status == TA_HDCP_STATUS__SUCCESS &&
1021	    msg_out->process.msg1_status == TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS)
1022		status = MOD_HDCP_STATUS_SUCCESS;
1023	else
1024		status = MOD_HDCP_STATUS_HDCP2_VALIDATE_STREAM_READY_FAILURE;
1025
1026	mutex_unlock(&psp->hdcp_context.mutex);
1027	return status;
1028}
1029