xref: /openbsd-src/sys/dev/pci/drm/amd/display/modules/hdcp/hdcp1_execution.c (revision c11f96349fa4c5fa2052ee76980ebcb13164f183)
1c349dbc7Sjsg /*
2c349dbc7Sjsg  * Copyright 2019 Advanced Micro Devices, Inc.
3c349dbc7Sjsg  *
4c349dbc7Sjsg  * Permission is hereby granted, free of charge, to any person obtaining a
5c349dbc7Sjsg  * copy of this software and associated documentation files (the "Software"),
6c349dbc7Sjsg  * to deal in the Software without restriction, including without limitation
7c349dbc7Sjsg  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8c349dbc7Sjsg  * and/or sell copies of the Software, and to permit persons to whom the
9c349dbc7Sjsg  * Software is furnished to do so, subject to the following conditions:
10c349dbc7Sjsg  *
11c349dbc7Sjsg  * The above copyright notice and this permission notice shall be included in
12c349dbc7Sjsg  * all copies or substantial portions of the Software.
13c349dbc7Sjsg  *
14c349dbc7Sjsg  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15c349dbc7Sjsg  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16c349dbc7Sjsg  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17c349dbc7Sjsg  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18c349dbc7Sjsg  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19c349dbc7Sjsg  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20c349dbc7Sjsg  * OTHER DEALINGS IN THE SOFTWARE.
21c349dbc7Sjsg  *
22c349dbc7Sjsg  * Authors: AMD
23c349dbc7Sjsg  *
24c349dbc7Sjsg  */
25c349dbc7Sjsg 
26c349dbc7Sjsg #include "hdcp.h"
27c349dbc7Sjsg 
28c349dbc7Sjsg static inline enum mod_hdcp_status validate_bksv(struct mod_hdcp *hdcp)
29c349dbc7Sjsg {
30c349dbc7Sjsg 	uint64_t n = 0;
31c349dbc7Sjsg 	uint8_t count = 0;
32560c8523Sjsg 	u8 bksv[sizeof(n)] = { };
33c349dbc7Sjsg 
34560c8523Sjsg 	memcpy(bksv, hdcp->auth.msg.hdcp1.bksv, sizeof(hdcp->auth.msg.hdcp1.bksv));
35560c8523Sjsg 	n = *(uint64_t *)bksv;
36c349dbc7Sjsg 
37c349dbc7Sjsg 	while (n) {
38c349dbc7Sjsg 		count++;
39c349dbc7Sjsg 		n &= (n - 1);
40c349dbc7Sjsg 	}
41c349dbc7Sjsg 	return (count == 20) ? MOD_HDCP_STATUS_SUCCESS :
42c349dbc7Sjsg 			MOD_HDCP_STATUS_HDCP1_INVALID_BKSV;
43c349dbc7Sjsg }
44c349dbc7Sjsg 
45c349dbc7Sjsg static inline enum mod_hdcp_status check_ksv_ready(struct mod_hdcp *hdcp)
46c349dbc7Sjsg {
47c349dbc7Sjsg 	if (is_dp_hdcp(hdcp))
48c349dbc7Sjsg 		return (hdcp->auth.msg.hdcp1.bstatus & DP_BSTATUS_READY) ?
49c349dbc7Sjsg 				MOD_HDCP_STATUS_SUCCESS :
50c349dbc7Sjsg 				MOD_HDCP_STATUS_HDCP1_KSV_LIST_NOT_READY;
51c349dbc7Sjsg 	return (hdcp->auth.msg.hdcp1.bcaps & DRM_HDCP_DDC_BCAPS_KSV_FIFO_READY) ?
52c349dbc7Sjsg 			MOD_HDCP_STATUS_SUCCESS :
53c349dbc7Sjsg 			MOD_HDCP_STATUS_HDCP1_KSV_LIST_NOT_READY;
54c349dbc7Sjsg }
55c349dbc7Sjsg 
56c349dbc7Sjsg static inline enum mod_hdcp_status check_hdcp_capable_dp(struct mod_hdcp *hdcp)
57c349dbc7Sjsg {
58c349dbc7Sjsg 	return (hdcp->auth.msg.hdcp1.bcaps & DP_BCAPS_HDCP_CAPABLE) ?
59c349dbc7Sjsg 			MOD_HDCP_STATUS_SUCCESS :
60c349dbc7Sjsg 			MOD_HDCP_STATUS_HDCP1_NOT_CAPABLE;
61c349dbc7Sjsg }
62c349dbc7Sjsg 
63c349dbc7Sjsg static inline enum mod_hdcp_status check_r0p_available_dp(struct mod_hdcp *hdcp)
64c349dbc7Sjsg {
65c349dbc7Sjsg 	enum mod_hdcp_status status;
66c349dbc7Sjsg 	if (is_dp_hdcp(hdcp)) {
67c349dbc7Sjsg 		status = (hdcp->auth.msg.hdcp1.bstatus &
68c349dbc7Sjsg 				DP_BSTATUS_R0_PRIME_READY) ?
69c349dbc7Sjsg 			MOD_HDCP_STATUS_SUCCESS :
70c349dbc7Sjsg 			MOD_HDCP_STATUS_HDCP1_R0_PRIME_PENDING;
71c349dbc7Sjsg 	} else {
72c349dbc7Sjsg 		status = MOD_HDCP_STATUS_INVALID_OPERATION;
73c349dbc7Sjsg 	}
74c349dbc7Sjsg 	return status;
75c349dbc7Sjsg }
76c349dbc7Sjsg 
77c349dbc7Sjsg static inline enum mod_hdcp_status check_link_integrity_dp(
78c349dbc7Sjsg 		struct mod_hdcp *hdcp)
79c349dbc7Sjsg {
80c349dbc7Sjsg 	return (hdcp->auth.msg.hdcp1.bstatus &
81c349dbc7Sjsg 			DP_BSTATUS_LINK_FAILURE) ?
82c349dbc7Sjsg 			MOD_HDCP_STATUS_HDCP1_LINK_INTEGRITY_FAILURE :
83c349dbc7Sjsg 			MOD_HDCP_STATUS_SUCCESS;
84c349dbc7Sjsg }
85c349dbc7Sjsg 
86c349dbc7Sjsg static inline enum mod_hdcp_status check_no_reauthentication_request_dp(
87c349dbc7Sjsg 		struct mod_hdcp *hdcp)
88c349dbc7Sjsg {
89c349dbc7Sjsg 	return (hdcp->auth.msg.hdcp1.bstatus & DP_BSTATUS_REAUTH_REQ) ?
90c349dbc7Sjsg 			MOD_HDCP_STATUS_HDCP1_REAUTH_REQUEST_ISSUED :
91c349dbc7Sjsg 			MOD_HDCP_STATUS_SUCCESS;
92c349dbc7Sjsg }
93c349dbc7Sjsg 
94c349dbc7Sjsg static inline enum mod_hdcp_status check_no_max_cascade(struct mod_hdcp *hdcp)
95c349dbc7Sjsg {
96c349dbc7Sjsg 	enum mod_hdcp_status status;
97c349dbc7Sjsg 
98c349dbc7Sjsg 	if (is_dp_hdcp(hdcp))
99c349dbc7Sjsg 		status = DRM_HDCP_MAX_CASCADE_EXCEEDED(hdcp->auth.msg.hdcp1.binfo_dp >> 8)
100c349dbc7Sjsg 				 ? MOD_HDCP_STATUS_HDCP1_MAX_CASCADE_EXCEEDED_FAILURE
101c349dbc7Sjsg 				 : MOD_HDCP_STATUS_SUCCESS;
102c349dbc7Sjsg 	else
103c349dbc7Sjsg 		status = DRM_HDCP_MAX_CASCADE_EXCEEDED(hdcp->auth.msg.hdcp1.bstatus >> 8)
104c349dbc7Sjsg 				 ? MOD_HDCP_STATUS_HDCP1_MAX_CASCADE_EXCEEDED_FAILURE
105c349dbc7Sjsg 				 : MOD_HDCP_STATUS_SUCCESS;
106c349dbc7Sjsg 	return status;
107c349dbc7Sjsg }
108c349dbc7Sjsg 
109c349dbc7Sjsg static inline enum mod_hdcp_status check_no_max_devs(struct mod_hdcp *hdcp)
110c349dbc7Sjsg {
111c349dbc7Sjsg 	enum mod_hdcp_status status;
112c349dbc7Sjsg 
113c349dbc7Sjsg 	if (is_dp_hdcp(hdcp))
114c349dbc7Sjsg 		status = DRM_HDCP_MAX_DEVICE_EXCEEDED(hdcp->auth.msg.hdcp1.binfo_dp) ?
115c349dbc7Sjsg 				MOD_HDCP_STATUS_HDCP1_MAX_DEVS_EXCEEDED_FAILURE :
116c349dbc7Sjsg 				MOD_HDCP_STATUS_SUCCESS;
117c349dbc7Sjsg 	else
118c349dbc7Sjsg 		status = DRM_HDCP_MAX_DEVICE_EXCEEDED(hdcp->auth.msg.hdcp1.bstatus) ?
119c349dbc7Sjsg 				MOD_HDCP_STATUS_HDCP1_MAX_DEVS_EXCEEDED_FAILURE :
120c349dbc7Sjsg 				MOD_HDCP_STATUS_SUCCESS;
121c349dbc7Sjsg 	return status;
122c349dbc7Sjsg }
123c349dbc7Sjsg 
124c349dbc7Sjsg static inline uint8_t get_device_count(struct mod_hdcp *hdcp)
125c349dbc7Sjsg {
126c349dbc7Sjsg 	return is_dp_hdcp(hdcp) ?
127c349dbc7Sjsg 			DRM_HDCP_NUM_DOWNSTREAM(hdcp->auth.msg.hdcp1.binfo_dp) :
128c349dbc7Sjsg 			DRM_HDCP_NUM_DOWNSTREAM(hdcp->auth.msg.hdcp1.bstatus);
129c349dbc7Sjsg }
130c349dbc7Sjsg 
131c349dbc7Sjsg static inline enum mod_hdcp_status check_device_count(struct mod_hdcp *hdcp)
132c349dbc7Sjsg {
1335ca02815Sjsg 	/* Avoid device count == 0 to do authentication */
1345ca02815Sjsg 	if (0 == get_device_count(hdcp)) {
1355ca02815Sjsg 		return MOD_HDCP_STATUS_HDCP1_DEVICE_COUNT_MISMATCH_FAILURE;
1365ca02815Sjsg 	}
1375ca02815Sjsg 
1385ca02815Sjsg 	/* Some MST display may choose to report the internal panel as an HDCP RX.
1395ca02815Sjsg 	 * To update this condition with 1(because the immediate repeater's internal
1405ca02815Sjsg 	 * panel is possibly not included in DEVICE_COUNT) + get_device_count(hdcp).
1415ca02815Sjsg 	 * Device count must be greater than or equal to tracked hdcp displays.
1425ca02815Sjsg 	 */
1435ca02815Sjsg 	return ((1 + get_device_count(hdcp)) < get_active_display_count(hdcp)) ?
144c349dbc7Sjsg 			MOD_HDCP_STATUS_HDCP1_DEVICE_COUNT_MISMATCH_FAILURE :
145c349dbc7Sjsg 			MOD_HDCP_STATUS_SUCCESS;
146c349dbc7Sjsg }
147c349dbc7Sjsg 
148c349dbc7Sjsg static enum mod_hdcp_status wait_for_active_rx(struct mod_hdcp *hdcp,
149c349dbc7Sjsg 		struct mod_hdcp_event_context *event_ctx,
150c349dbc7Sjsg 		struct mod_hdcp_transition_input_hdcp1 *input)
151c349dbc7Sjsg {
152c349dbc7Sjsg 	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
153c349dbc7Sjsg 
154c349dbc7Sjsg 	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
155c349dbc7Sjsg 		event_ctx->unexpected_event = 1;
156c349dbc7Sjsg 		goto out;
157c349dbc7Sjsg 	}
158c349dbc7Sjsg 
159c349dbc7Sjsg 	if (!mod_hdcp_execute_and_set(mod_hdcp_read_bksv,
160c349dbc7Sjsg 			&input->bksv_read, &status,
161c349dbc7Sjsg 			hdcp, "bksv_read"))
162c349dbc7Sjsg 		goto out;
163c349dbc7Sjsg 	if (!mod_hdcp_execute_and_set(mod_hdcp_read_bcaps,
164c349dbc7Sjsg 			&input->bcaps_read, &status,
165c349dbc7Sjsg 			hdcp, "bcaps_read"))
166c349dbc7Sjsg 		goto out;
167c349dbc7Sjsg out:
168c349dbc7Sjsg 	return status;
169c349dbc7Sjsg }
170c349dbc7Sjsg 
171c349dbc7Sjsg static enum mod_hdcp_status exchange_ksvs(struct mod_hdcp *hdcp,
172c349dbc7Sjsg 		struct mod_hdcp_event_context *event_ctx,
173c349dbc7Sjsg 		struct mod_hdcp_transition_input_hdcp1 *input)
174c349dbc7Sjsg {
175c349dbc7Sjsg 	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
176c349dbc7Sjsg 
177c349dbc7Sjsg 	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
178c349dbc7Sjsg 		event_ctx->unexpected_event = 1;
179c349dbc7Sjsg 		goto out;
180c349dbc7Sjsg 	}
181c349dbc7Sjsg 
182c349dbc7Sjsg 	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp1_create_session,
183c349dbc7Sjsg 			&input->create_session, &status,
184c349dbc7Sjsg 			hdcp, "create_session"))
185c349dbc7Sjsg 		goto out;
186c349dbc7Sjsg 	if (!mod_hdcp_execute_and_set(mod_hdcp_write_an,
187c349dbc7Sjsg 			&input->an_write, &status,
188c349dbc7Sjsg 			hdcp, "an_write"))
189c349dbc7Sjsg 		goto out;
190c349dbc7Sjsg 	if (!mod_hdcp_execute_and_set(mod_hdcp_write_aksv,
191c349dbc7Sjsg 			&input->aksv_write, &status,
192c349dbc7Sjsg 			hdcp, "aksv_write"))
193c349dbc7Sjsg 		goto out;
194c349dbc7Sjsg 	if (!mod_hdcp_execute_and_set(mod_hdcp_read_bksv,
195c349dbc7Sjsg 			&input->bksv_read, &status,
196c349dbc7Sjsg 			hdcp, "bksv_read"))
197c349dbc7Sjsg 		goto out;
198c349dbc7Sjsg 	if (!mod_hdcp_execute_and_set(validate_bksv,
199c349dbc7Sjsg 			&input->bksv_validation, &status,
200c349dbc7Sjsg 			hdcp, "bksv_validation"))
201c349dbc7Sjsg 		goto out;
202c349dbc7Sjsg 	if (hdcp->auth.msg.hdcp1.ainfo) {
203c349dbc7Sjsg 		if (!mod_hdcp_execute_and_set(mod_hdcp_write_ainfo,
204c349dbc7Sjsg 				&input->ainfo_write, &status,
205c349dbc7Sjsg 				hdcp, "ainfo_write"))
206c349dbc7Sjsg 			goto out;
207c349dbc7Sjsg 	}
208c349dbc7Sjsg out:
209c349dbc7Sjsg 	return status;
210c349dbc7Sjsg }
211c349dbc7Sjsg 
212c349dbc7Sjsg static enum mod_hdcp_status computations_validate_rx_test_for_repeater(
213c349dbc7Sjsg 		struct mod_hdcp *hdcp,
214c349dbc7Sjsg 		struct mod_hdcp_event_context *event_ctx,
215c349dbc7Sjsg 		struct mod_hdcp_transition_input_hdcp1 *input)
216c349dbc7Sjsg {
217c349dbc7Sjsg 	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
218c349dbc7Sjsg 
219c349dbc7Sjsg 	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
220c349dbc7Sjsg 		event_ctx->unexpected_event = 1;
221c349dbc7Sjsg 		goto out;
222c349dbc7Sjsg 	}
223c349dbc7Sjsg 
224c349dbc7Sjsg 	if (!mod_hdcp_execute_and_set(mod_hdcp_read_r0p,
225c349dbc7Sjsg 			&input->r0p_read, &status,
226c349dbc7Sjsg 			hdcp, "r0p_read"))
227c349dbc7Sjsg 		goto out;
228c349dbc7Sjsg 	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp1_validate_rx,
229c349dbc7Sjsg 			&input->rx_validation, &status,
230c349dbc7Sjsg 			hdcp, "rx_validation"))
231c349dbc7Sjsg 		goto out;
232c349dbc7Sjsg 	if (hdcp->connection.is_repeater) {
233c349dbc7Sjsg 		if (!hdcp->connection.link.adjust.hdcp1.postpone_encryption)
234c349dbc7Sjsg 			if (!mod_hdcp_execute_and_set(
235c349dbc7Sjsg 					mod_hdcp_hdcp1_enable_encryption,
236c349dbc7Sjsg 					&input->encryption, &status,
237c349dbc7Sjsg 					hdcp, "encryption"))
238c349dbc7Sjsg 				goto out;
239c349dbc7Sjsg 	} else {
240c349dbc7Sjsg 		if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp1_enable_encryption,
241c349dbc7Sjsg 				&input->encryption, &status,
242c349dbc7Sjsg 				hdcp, "encryption"))
243c349dbc7Sjsg 			goto out;
244c349dbc7Sjsg 		if (is_dp_mst_hdcp(hdcp))
245c349dbc7Sjsg 			if (!mod_hdcp_execute_and_set(
246c349dbc7Sjsg 					mod_hdcp_hdcp1_enable_dp_stream_encryption,
247c349dbc7Sjsg 					&input->stream_encryption_dp, &status,
248c349dbc7Sjsg 					hdcp, "stream_encryption_dp"))
249c349dbc7Sjsg 				goto out;
250c349dbc7Sjsg 	}
251c349dbc7Sjsg out:
252c349dbc7Sjsg 	return status;
253c349dbc7Sjsg }
254c349dbc7Sjsg 
255c349dbc7Sjsg static enum mod_hdcp_status authenticated(struct mod_hdcp *hdcp,
256c349dbc7Sjsg 		struct mod_hdcp_event_context *event_ctx,
257c349dbc7Sjsg 		struct mod_hdcp_transition_input_hdcp1 *input)
258c349dbc7Sjsg {
259c349dbc7Sjsg 	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
260c349dbc7Sjsg 
261c349dbc7Sjsg 	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
262c349dbc7Sjsg 		event_ctx->unexpected_event = 1;
263c349dbc7Sjsg 		goto out;
264c349dbc7Sjsg 	}
265c349dbc7Sjsg 
2665ca02815Sjsg 	mod_hdcp_execute_and_set(mod_hdcp_hdcp1_link_maintenance,
267c349dbc7Sjsg 			&input->link_maintenance, &status,
2685ca02815Sjsg 			hdcp, "link_maintenance");
269c349dbc7Sjsg out:
270c349dbc7Sjsg 	return status;
271c349dbc7Sjsg }
272c349dbc7Sjsg 
273c349dbc7Sjsg static enum mod_hdcp_status wait_for_ready(struct mod_hdcp *hdcp,
274c349dbc7Sjsg 		struct mod_hdcp_event_context *event_ctx,
275c349dbc7Sjsg 		struct mod_hdcp_transition_input_hdcp1 *input)
276c349dbc7Sjsg {
277c349dbc7Sjsg 	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
278c349dbc7Sjsg 
279c349dbc7Sjsg 	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
280c349dbc7Sjsg 			event_ctx->event != MOD_HDCP_EVENT_CPIRQ &&
281c349dbc7Sjsg 			event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
282c349dbc7Sjsg 		event_ctx->unexpected_event = 1;
283c349dbc7Sjsg 		goto out;
284c349dbc7Sjsg 	}
285c349dbc7Sjsg 
286c349dbc7Sjsg 	if (is_dp_hdcp(hdcp)) {
287c349dbc7Sjsg 		if (!mod_hdcp_execute_and_set(mod_hdcp_read_bstatus,
288c349dbc7Sjsg 				&input->bstatus_read, &status,
289c349dbc7Sjsg 				hdcp, "bstatus_read"))
290c349dbc7Sjsg 			goto out;
291c349dbc7Sjsg 		if (!mod_hdcp_execute_and_set(check_link_integrity_dp,
292c349dbc7Sjsg 				&input->link_integrity_check, &status,
293c349dbc7Sjsg 				hdcp, "link_integrity_check"))
294c349dbc7Sjsg 			goto out;
295c349dbc7Sjsg 		if (!mod_hdcp_execute_and_set(check_no_reauthentication_request_dp,
296c349dbc7Sjsg 				&input->reauth_request_check, &status,
297c349dbc7Sjsg 				hdcp, "reauth_request_check"))
298c349dbc7Sjsg 			goto out;
299c349dbc7Sjsg 	} else {
300c349dbc7Sjsg 		if (!mod_hdcp_execute_and_set(mod_hdcp_read_bcaps,
301c349dbc7Sjsg 				&input->bcaps_read, &status,
302c349dbc7Sjsg 				hdcp, "bcaps_read"))
303c349dbc7Sjsg 			goto out;
304c349dbc7Sjsg 	}
305c349dbc7Sjsg 	if (!mod_hdcp_execute_and_set(check_ksv_ready,
306c349dbc7Sjsg 			&input->ready_check, &status,
307c349dbc7Sjsg 			hdcp, "ready_check"))
308c349dbc7Sjsg 		goto out;
309c349dbc7Sjsg out:
310c349dbc7Sjsg 	return status;
311c349dbc7Sjsg }
312c349dbc7Sjsg 
313c349dbc7Sjsg static enum mod_hdcp_status read_ksv_list(struct mod_hdcp *hdcp,
314c349dbc7Sjsg 		struct mod_hdcp_event_context *event_ctx,
315c349dbc7Sjsg 		struct mod_hdcp_transition_input_hdcp1 *input)
316c349dbc7Sjsg {
317c349dbc7Sjsg 	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
318c349dbc7Sjsg 	uint8_t device_count;
319c349dbc7Sjsg 
320c349dbc7Sjsg 	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
321c349dbc7Sjsg 		event_ctx->unexpected_event = 1;
322c349dbc7Sjsg 		goto out;
323c349dbc7Sjsg 	}
324c349dbc7Sjsg 
325c349dbc7Sjsg 	if (is_dp_hdcp(hdcp)) {
326c349dbc7Sjsg 		if (!mod_hdcp_execute_and_set(mod_hdcp_read_binfo,
327c349dbc7Sjsg 				&input->binfo_read_dp, &status,
328c349dbc7Sjsg 				hdcp, "binfo_read_dp"))
329c349dbc7Sjsg 			goto out;
330c349dbc7Sjsg 	} else {
331c349dbc7Sjsg 		if (!mod_hdcp_execute_and_set(mod_hdcp_read_bstatus,
332c349dbc7Sjsg 				&input->bstatus_read, &status,
333c349dbc7Sjsg 				hdcp, "bstatus_read"))
334c349dbc7Sjsg 			goto out;
335c349dbc7Sjsg 	}
336c349dbc7Sjsg 	if (!mod_hdcp_execute_and_set(check_no_max_cascade,
337c349dbc7Sjsg 			&input->max_cascade_check, &status,
338c349dbc7Sjsg 			hdcp, "max_cascade_check"))
339c349dbc7Sjsg 		goto out;
340c349dbc7Sjsg 	if (!mod_hdcp_execute_and_set(check_no_max_devs,
341c349dbc7Sjsg 			&input->max_devs_check, &status,
342c349dbc7Sjsg 			hdcp, "max_devs_check"))
343c349dbc7Sjsg 		goto out;
344c349dbc7Sjsg 	if (!mod_hdcp_execute_and_set(check_device_count,
345c349dbc7Sjsg 			&input->device_count_check, &status,
346c349dbc7Sjsg 			hdcp, "device_count_check"))
347c349dbc7Sjsg 		goto out;
348c349dbc7Sjsg 	device_count = get_device_count(hdcp);
349c349dbc7Sjsg 	hdcp->auth.msg.hdcp1.ksvlist_size = device_count*5;
350c349dbc7Sjsg 	if (!mod_hdcp_execute_and_set(mod_hdcp_read_ksvlist,
351c349dbc7Sjsg 			&input->ksvlist_read, &status,
352c349dbc7Sjsg 			hdcp, "ksvlist_read"))
353c349dbc7Sjsg 		goto out;
354c349dbc7Sjsg 	if (!mod_hdcp_execute_and_set(mod_hdcp_read_vp,
355c349dbc7Sjsg 			&input->vp_read, &status,
356c349dbc7Sjsg 			hdcp, "vp_read"))
357c349dbc7Sjsg 		goto out;
358c349dbc7Sjsg 	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp1_validate_ksvlist_vp,
359c349dbc7Sjsg 			&input->ksvlist_vp_validation, &status,
360c349dbc7Sjsg 			hdcp, "ksvlist_vp_validation"))
361c349dbc7Sjsg 		goto out;
362c349dbc7Sjsg 	if (input->encryption != PASS)
363c349dbc7Sjsg 		if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp1_enable_encryption,
364c349dbc7Sjsg 				&input->encryption, &status,
365c349dbc7Sjsg 				hdcp, "encryption"))
366c349dbc7Sjsg 			goto out;
367c349dbc7Sjsg 	if (is_dp_mst_hdcp(hdcp))
368c349dbc7Sjsg 		if (!mod_hdcp_execute_and_set(
369c349dbc7Sjsg 				mod_hdcp_hdcp1_enable_dp_stream_encryption,
370c349dbc7Sjsg 				&input->stream_encryption_dp, &status,
371c349dbc7Sjsg 				hdcp, "stream_encryption_dp"))
372c349dbc7Sjsg 			goto out;
373c349dbc7Sjsg out:
374c349dbc7Sjsg 	return status;
375c349dbc7Sjsg }
376c349dbc7Sjsg 
377c349dbc7Sjsg static enum mod_hdcp_status determine_rx_hdcp_capable_dp(struct mod_hdcp *hdcp,
378c349dbc7Sjsg 		struct mod_hdcp_event_context *event_ctx,
379c349dbc7Sjsg 		struct mod_hdcp_transition_input_hdcp1 *input)
380c349dbc7Sjsg {
381c349dbc7Sjsg 	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
382c349dbc7Sjsg 
383c349dbc7Sjsg 	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
384c349dbc7Sjsg 		event_ctx->unexpected_event = 1;
385c349dbc7Sjsg 		goto out;
386c349dbc7Sjsg 	}
387c349dbc7Sjsg 
388c349dbc7Sjsg 	if (!mod_hdcp_execute_and_set(mod_hdcp_read_bcaps,
389c349dbc7Sjsg 			&input->bcaps_read, &status,
390c349dbc7Sjsg 			hdcp, "bcaps_read"))
391c349dbc7Sjsg 		goto out;
392c349dbc7Sjsg 	if (!mod_hdcp_execute_and_set(check_hdcp_capable_dp,
393c349dbc7Sjsg 			&input->hdcp_capable_dp, &status,
394c349dbc7Sjsg 			hdcp, "hdcp_capable_dp"))
395c349dbc7Sjsg 		goto out;
396c349dbc7Sjsg out:
397c349dbc7Sjsg 	return status;
398c349dbc7Sjsg }
399c349dbc7Sjsg 
400c349dbc7Sjsg static enum mod_hdcp_status wait_for_r0_prime_dp(struct mod_hdcp *hdcp,
401c349dbc7Sjsg 		struct mod_hdcp_event_context *event_ctx,
402c349dbc7Sjsg 		struct mod_hdcp_transition_input_hdcp1 *input)
403c349dbc7Sjsg {
404c349dbc7Sjsg 	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
405c349dbc7Sjsg 
406c349dbc7Sjsg 	if (event_ctx->event != MOD_HDCP_EVENT_CPIRQ &&
407c349dbc7Sjsg 			event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
408c349dbc7Sjsg 		event_ctx->unexpected_event = 1;
409c349dbc7Sjsg 		goto out;
410c349dbc7Sjsg 	}
411c349dbc7Sjsg 
412c349dbc7Sjsg 	if (!mod_hdcp_execute_and_set(mod_hdcp_read_bstatus,
413c349dbc7Sjsg 			&input->bstatus_read, &status,
414c349dbc7Sjsg 			hdcp, "bstatus_read"))
415c349dbc7Sjsg 		goto out;
416c349dbc7Sjsg 	if (!mod_hdcp_execute_and_set(check_r0p_available_dp,
417c349dbc7Sjsg 			&input->r0p_available_dp, &status,
418c349dbc7Sjsg 			hdcp, "r0p_available_dp"))
419c349dbc7Sjsg 		goto out;
420c349dbc7Sjsg out:
421c349dbc7Sjsg 	return status;
422c349dbc7Sjsg }
423c349dbc7Sjsg 
424c349dbc7Sjsg static enum mod_hdcp_status authenticated_dp(struct mod_hdcp *hdcp,
425c349dbc7Sjsg 		struct mod_hdcp_event_context *event_ctx,
426c349dbc7Sjsg 		struct mod_hdcp_transition_input_hdcp1 *input)
427c349dbc7Sjsg {
428c349dbc7Sjsg 	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
429c349dbc7Sjsg 
430c349dbc7Sjsg 	if (event_ctx->event != MOD_HDCP_EVENT_CPIRQ) {
431c349dbc7Sjsg 		event_ctx->unexpected_event = 1;
432c349dbc7Sjsg 		goto out;
433c349dbc7Sjsg 	}
434c349dbc7Sjsg 
435*c11f9634Sjsg 	mod_hdcp_execute_and_set(mod_hdcp_read_bstatus,
436c349dbc7Sjsg 			&input->bstatus_read, &status,
437*c11f9634Sjsg 			hdcp, "bstatus_read");
438*c11f9634Sjsg 
439*c11f9634Sjsg 	mod_hdcp_execute_and_set(check_link_integrity_dp,
440c349dbc7Sjsg 			&input->link_integrity_check, &status,
441*c11f9634Sjsg 			hdcp, "link_integrity_check");
442*c11f9634Sjsg 
443*c11f9634Sjsg 	mod_hdcp_execute_and_set(check_no_reauthentication_request_dp,
444c349dbc7Sjsg 			&input->reauth_request_check, &status,
445*c11f9634Sjsg 			hdcp, "reauth_request_check");
446*c11f9634Sjsg 
447c349dbc7Sjsg out:
448c349dbc7Sjsg 	return status;
449c349dbc7Sjsg }
450c349dbc7Sjsg 
451c349dbc7Sjsg uint8_t mod_hdcp_execute_and_set(
452c349dbc7Sjsg 		mod_hdcp_action func, uint8_t *flag,
453c349dbc7Sjsg 		enum mod_hdcp_status *status, struct mod_hdcp *hdcp, char *str)
454c349dbc7Sjsg {
455c349dbc7Sjsg 	*status = func(hdcp);
456c349dbc7Sjsg 	if (*status == MOD_HDCP_STATUS_SUCCESS && *flag != PASS) {
457c349dbc7Sjsg 		HDCP_INPUT_PASS_TRACE(hdcp, str);
458c349dbc7Sjsg 		*flag = PASS;
459c349dbc7Sjsg 	} else if (*status != MOD_HDCP_STATUS_SUCCESS && *flag != FAIL) {
460c349dbc7Sjsg 		HDCP_INPUT_FAIL_TRACE(hdcp, str);
461c349dbc7Sjsg 		*flag = FAIL;
462c349dbc7Sjsg 	}
463c349dbc7Sjsg 	return (*status == MOD_HDCP_STATUS_SUCCESS);
464c349dbc7Sjsg }
465c349dbc7Sjsg 
466c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp1_execution(struct mod_hdcp *hdcp,
467c349dbc7Sjsg 		struct mod_hdcp_event_context *event_ctx,
468c349dbc7Sjsg 		struct mod_hdcp_transition_input_hdcp1 *input)
469c349dbc7Sjsg {
470c349dbc7Sjsg 	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
471c349dbc7Sjsg 
472c349dbc7Sjsg 	switch (current_state(hdcp)) {
473c349dbc7Sjsg 	case H1_A0_WAIT_FOR_ACTIVE_RX:
474c349dbc7Sjsg 		status = wait_for_active_rx(hdcp, event_ctx, input);
475c349dbc7Sjsg 		break;
476c349dbc7Sjsg 	case H1_A1_EXCHANGE_KSVS:
477c349dbc7Sjsg 		status = exchange_ksvs(hdcp, event_ctx, input);
478c349dbc7Sjsg 		break;
479c349dbc7Sjsg 	case H1_A2_COMPUTATIONS_A3_VALIDATE_RX_A6_TEST_FOR_REPEATER:
480c349dbc7Sjsg 		status = computations_validate_rx_test_for_repeater(hdcp,
481c349dbc7Sjsg 				event_ctx, input);
482c349dbc7Sjsg 		break;
483c349dbc7Sjsg 	case H1_A45_AUTHENTICATED:
484c349dbc7Sjsg 		status = authenticated(hdcp, event_ctx, input);
485c349dbc7Sjsg 		break;
486c349dbc7Sjsg 	case H1_A8_WAIT_FOR_READY:
487c349dbc7Sjsg 		status = wait_for_ready(hdcp, event_ctx, input);
488c349dbc7Sjsg 		break;
489c349dbc7Sjsg 	case H1_A9_READ_KSV_LIST:
490c349dbc7Sjsg 		status = read_ksv_list(hdcp, event_ctx, input);
491c349dbc7Sjsg 		break;
492c349dbc7Sjsg 	default:
493c349dbc7Sjsg 		status = MOD_HDCP_STATUS_INVALID_STATE;
494c349dbc7Sjsg 		break;
495c349dbc7Sjsg 	}
496c349dbc7Sjsg 
497c349dbc7Sjsg 	return status;
498c349dbc7Sjsg }
499c349dbc7Sjsg 
5001bb76ff1Sjsg enum mod_hdcp_status mod_hdcp_hdcp1_dp_execution(struct mod_hdcp *hdcp,
501c349dbc7Sjsg 						 struct mod_hdcp_event_context *event_ctx,
502c349dbc7Sjsg 						 struct mod_hdcp_transition_input_hdcp1 *input)
503c349dbc7Sjsg {
504c349dbc7Sjsg 	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
505c349dbc7Sjsg 
506c349dbc7Sjsg 	switch (current_state(hdcp)) {
507c349dbc7Sjsg 	case D1_A0_DETERMINE_RX_HDCP_CAPABLE:
508c349dbc7Sjsg 		status = determine_rx_hdcp_capable_dp(hdcp, event_ctx, input);
509c349dbc7Sjsg 		break;
510c349dbc7Sjsg 	case D1_A1_EXCHANGE_KSVS:
511c349dbc7Sjsg 		status = exchange_ksvs(hdcp, event_ctx, input);
512c349dbc7Sjsg 		break;
513c349dbc7Sjsg 	case D1_A23_WAIT_FOR_R0_PRIME:
514c349dbc7Sjsg 		status = wait_for_r0_prime_dp(hdcp, event_ctx, input);
515c349dbc7Sjsg 		break;
516c349dbc7Sjsg 	case D1_A2_COMPUTATIONS_A3_VALIDATE_RX_A5_TEST_FOR_REPEATER:
517c349dbc7Sjsg 		status = computations_validate_rx_test_for_repeater(
518c349dbc7Sjsg 				hdcp, event_ctx, input);
519c349dbc7Sjsg 		break;
520c349dbc7Sjsg 	case D1_A4_AUTHENTICATED:
521c349dbc7Sjsg 		status = authenticated_dp(hdcp, event_ctx, input);
522c349dbc7Sjsg 		break;
523c349dbc7Sjsg 	case D1_A6_WAIT_FOR_READY:
524c349dbc7Sjsg 		status = wait_for_ready(hdcp, event_ctx, input);
525c349dbc7Sjsg 		break;
526c349dbc7Sjsg 	case D1_A7_READ_KSV_LIST:
527c349dbc7Sjsg 		status = read_ksv_list(hdcp, event_ctx, input);
528c349dbc7Sjsg 		break;
529c349dbc7Sjsg 	default:
530c349dbc7Sjsg 		status = MOD_HDCP_STATUS_INVALID_STATE;
531c349dbc7Sjsg 		break;
532c349dbc7Sjsg 	}
533c349dbc7Sjsg 
534c349dbc7Sjsg 	return status;
535c349dbc7Sjsg }
536