File Index
Files and directories
Sign in
FILE

hdcp2_execution.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_execution.c C
  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#include <linux/delay.h>
 27
 28#include "hdcp.h"
 29
 30static inline uint16_t get_hdmi_rxstatus_msg_size(const uint8_t rxstatus[2])
 31{
 32	return HDCP_2_2_HDMI_RXSTATUS_MSG_SZ_HI(rxstatus[1]) << 8 | rxstatus[0];
 33}
 34
 35static inline enum mod_hdcp_status check_receiver_id_list_ready(struct mod_hdcp *hdcp)
 36{
 37	uint8_t is_ready = 0;
 38
 39	if (is_dp_hdcp(hdcp))
 40		is_ready = HDCP_2_2_DP_RXSTATUS_READY(hdcp->auth.msg.hdcp2.rxstatus_dp) ? 1 : 0;
 41	else
 42		is_ready = (HDCP_2_2_HDMI_RXSTATUS_READY(hdcp->auth.msg.hdcp2.rxstatus[1]) &&
 43				get_hdmi_rxstatus_msg_size(hdcp->auth.msg.hdcp2.rxstatus) != 0) ? 1 : 0;
 44	return is_ready ? MOD_HDCP_STATUS_SUCCESS :
 45			MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_NOT_READY;
 46}
 47
 48static inline enum mod_hdcp_status check_hdcp2_capable(struct mod_hdcp *hdcp)
 49{
 50	enum mod_hdcp_status status;
 51	struct mod_hdcp_trace *trace = &hdcp->connection.trace;
 52
 53	if (is_dp_hdcp(hdcp))
 54		status = (hdcp->auth.msg.hdcp2.rxcaps_dp[0] == HDCP_2_2_RX_CAPS_VERSION_VAL) &&
 55				HDCP_2_2_DP_HDCP_CAPABLE(hdcp->auth.msg.hdcp2.rxcaps_dp[2]) ?
 56				MOD_HDCP_STATUS_SUCCESS :
 57				MOD_HDCP_STATUS_HDCP2_NOT_CAPABLE;
 58	else
 59		status = (hdcp->auth.msg.hdcp2.hdcp2version_hdmi
 60				 & HDCP_2_2_HDMI_SUPPORT_MASK)
 61				? MOD_HDCP_STATUS_SUCCESS
 62				: MOD_HDCP_STATUS_HDCP2_NOT_CAPABLE;
 63
 64	if (status == MOD_HDCP_STATUS_SUCCESS)
 65		trace->hdcp2.attempt_count++;
 66
 67	return status;
 68}
 69
 70static inline enum mod_hdcp_status check_reauthentication_request(
 71		struct mod_hdcp *hdcp)
 72{
 73	uint8_t ret = 0;
 74
 75	if (is_dp_hdcp(hdcp))
 76		ret = HDCP_2_2_DP_RXSTATUS_REAUTH_REQ(hdcp->auth.msg.hdcp2.rxstatus_dp) ?
 77				MOD_HDCP_STATUS_HDCP2_REAUTH_REQUEST :
 78				MOD_HDCP_STATUS_SUCCESS;
 79	else
 80		ret = HDCP_2_2_HDMI_RXSTATUS_REAUTH_REQ(hdcp->auth.msg.hdcp2.rxstatus[1]) ?
 81				MOD_HDCP_STATUS_HDCP2_REAUTH_REQUEST :
 82				MOD_HDCP_STATUS_SUCCESS;
 83	return ret;
 84}
 85
 86static inline enum mod_hdcp_status check_link_integrity_failure_dp(
 87		struct mod_hdcp *hdcp)
 88{
 89	return HDCP_2_2_DP_RXSTATUS_LINK_FAILED(hdcp->auth.msg.hdcp2.rxstatus_dp) ?
 90			MOD_HDCP_STATUS_HDCP2_REAUTH_LINK_INTEGRITY_FAILURE :
 91			MOD_HDCP_STATUS_SUCCESS;
 92}
 93
 94static enum mod_hdcp_status check_ake_cert_available(struct mod_hdcp *hdcp)
 95{
 96	enum mod_hdcp_status status;
 97
 98	if (is_dp_hdcp(hdcp)) {
 99		status = MOD_HDCP_STATUS_SUCCESS;
100	} else {
101		status = mod_hdcp_read_rxstatus(hdcp);
102		if (status == MOD_HDCP_STATUS_SUCCESS) {
103			const uint16_t size = get_hdmi_rxstatus_msg_size(hdcp->auth.msg.hdcp2.rxstatus);
104			status = (size == sizeof(hdcp->auth.msg.hdcp2.ake_cert)) ?
105					MOD_HDCP_STATUS_SUCCESS :
106					MOD_HDCP_STATUS_HDCP2_AKE_CERT_PENDING;
107		}
108	}
109	return status;
110}
111
112static enum mod_hdcp_status check_h_prime_available(struct mod_hdcp *hdcp)
113{
114	enum mod_hdcp_status status;
115
116	status = mod_hdcp_read_rxstatus(hdcp);
117	if (status != MOD_HDCP_STATUS_SUCCESS)
118		goto out;
119
120	if (is_dp_hdcp(hdcp)) {
121		status = HDCP_2_2_DP_RXSTATUS_H_PRIME(hdcp->auth.msg.hdcp2.rxstatus_dp) ?
122				MOD_HDCP_STATUS_SUCCESS :
123				MOD_HDCP_STATUS_HDCP2_H_PRIME_PENDING;
124	} else {
125		const uint16_t size = get_hdmi_rxstatus_msg_size(hdcp->auth.msg.hdcp2.rxstatus);
126		status = (size == sizeof(hdcp->auth.msg.hdcp2.ake_h_prime)) ?
127				MOD_HDCP_STATUS_SUCCESS :
128				MOD_HDCP_STATUS_HDCP2_H_PRIME_PENDING;
129	}
130out:
131	return status;
132}
133
134static enum mod_hdcp_status check_pairing_info_available(struct mod_hdcp *hdcp)
135{
136	enum mod_hdcp_status status;
137
138	status = mod_hdcp_read_rxstatus(hdcp);
139	if (status != MOD_HDCP_STATUS_SUCCESS)
140		goto out;
141
142	if (is_dp_hdcp(hdcp)) {
143		status = HDCP_2_2_DP_RXSTATUS_PAIRING(hdcp->auth.msg.hdcp2.rxstatus_dp) ?
144				MOD_HDCP_STATUS_SUCCESS :
145				MOD_HDCP_STATUS_HDCP2_PAIRING_INFO_PENDING;
146	} else {
147		const uint16_t size = get_hdmi_rxstatus_msg_size(hdcp->auth.msg.hdcp2.rxstatus);
148		status = (size == sizeof(hdcp->auth.msg.hdcp2.ake_pairing_info)) ?
149				MOD_HDCP_STATUS_SUCCESS :
150				MOD_HDCP_STATUS_HDCP2_PAIRING_INFO_PENDING;
151	}
152out:
153	return status;
154}
155
156static enum mod_hdcp_status poll_l_prime_available(struct mod_hdcp *hdcp)
157{
158	enum mod_hdcp_status status = MOD_HDCP_STATUS_FAILURE;
159	uint16_t max_wait = 20; // units of ms
160	uint16_t num_polls = 5;
161	uint16_t wait_time = max_wait / num_polls;
162
163	if (is_dp_hdcp(hdcp))
164		status = MOD_HDCP_STATUS_INVALID_OPERATION;
165	else
166		for (; num_polls; num_polls--) {
167			msleep(wait_time);
168
169			status = mod_hdcp_read_rxstatus(hdcp);
170			if (status != MOD_HDCP_STATUS_SUCCESS)
171				break;
172
173			const uint16_t size = get_hdmi_rxstatus_msg_size(hdcp->auth.msg.hdcp2.rxstatus);
174			status = (size == sizeof(hdcp->auth.msg.hdcp2.lc_l_prime)) ?
175					MOD_HDCP_STATUS_SUCCESS :
176					MOD_HDCP_STATUS_HDCP2_L_PRIME_PENDING;
177			if (status == MOD_HDCP_STATUS_SUCCESS)
178				break;
179		}
180	return status;
181}
182
183static enum mod_hdcp_status check_stream_ready_available(struct mod_hdcp *hdcp)
184{
185	enum mod_hdcp_status status;
186
187	if (is_dp_hdcp(hdcp)) {
188		status = MOD_HDCP_STATUS_INVALID_OPERATION;
189	} else {
190		status = mod_hdcp_read_rxstatus(hdcp);
191		if (status != MOD_HDCP_STATUS_SUCCESS)
192			goto out;
193		const uint16_t size = get_hdmi_rxstatus_msg_size(hdcp->auth.msg.hdcp2.rxstatus);
194		status = (size == sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready)) ?
195				MOD_HDCP_STATUS_SUCCESS :
196				MOD_HDCP_STATUS_HDCP2_STREAM_READY_PENDING;
197	}
198out:
199	return status;
200}
201
202static inline uint8_t get_device_count(struct mod_hdcp *hdcp)
203{
204	return HDCP_2_2_DEV_COUNT_LO(hdcp->auth.msg.hdcp2.rx_id_list[2]) +
205			(HDCP_2_2_DEV_COUNT_HI(hdcp->auth.msg.hdcp2.rx_id_list[1]) << 4);
206}
207
208static enum mod_hdcp_status check_device_count(struct mod_hdcp *hdcp)
209{
210	struct mod_hdcp_trace *trace = &hdcp->connection.trace;
211
212	/* Avoid device count == 0 to do authentication */
213	if (get_device_count(hdcp) == 0)
214		return MOD_HDCP_STATUS_HDCP1_DEVICE_COUNT_MISMATCH_FAILURE;
215
216	trace->hdcp2.downstream_device_count = get_device_count(hdcp);
217	trace->hdcp2.hdcp1_device_downstream =
218			HDCP_2_2_HDCP1_DEVICE_CONNECTED(hdcp->auth.msg.hdcp2.rx_id_list[2]);
219	trace->hdcp2.hdcp2_legacy_device_downstream =
220			HDCP_2_2_HDCP_2_0_REP_CONNECTED(hdcp->auth.msg.hdcp2.rx_id_list[2]);
221	/* Some MST display may choose to report the internal panel as an HDCP RX.   */
222	/* To update this condition with 1(because the immediate repeater's internal */
223	/* panel is possibly not included in DEVICE_COUNT) + get_device_count(hdcp). */
224	/* Device count must be greater than or equal to tracked hdcp displays.      */
225	return ((1 + get_device_count(hdcp)) < get_active_display_count(hdcp)) ?
226			MOD_HDCP_STATUS_HDCP2_DEVICE_COUNT_MISMATCH_FAILURE :
227			MOD_HDCP_STATUS_SUCCESS;
228}
229
230static uint8_t process_rxstatus(struct mod_hdcp *hdcp,
231		struct mod_hdcp_event_context *event_ctx,
232		struct mod_hdcp_transition_input_hdcp2 *input,
233		enum mod_hdcp_status *status)
234{
235	if (!mod_hdcp_execute_and_set(mod_hdcp_read_rxstatus,
236			&input->rxstatus_read, status,
237			hdcp, "rxstatus_read"))
238		goto out;
239	if (!mod_hdcp_execute_and_set(check_reauthentication_request,
240			&input->reauth_request_check, status,
241			hdcp, "reauth_request_check"))
242		goto out;
243	if (is_dp_hdcp(hdcp)) {
244		if (!mod_hdcp_execute_and_set(check_link_integrity_failure_dp,
245				&input->link_integrity_check_dp, status,
246				hdcp, "link_integrity_check_dp"))
247			goto out;
248	}
249	if (hdcp->connection.is_repeater)
250		if (check_receiver_id_list_ready(hdcp) ==
251				MOD_HDCP_STATUS_SUCCESS) {
252			HDCP_INPUT_PASS_TRACE(hdcp, "rx_id_list_ready");
253			event_ctx->rx_id_list_ready = 1;
254			if (is_dp_hdcp(hdcp))
255				hdcp->auth.msg.hdcp2.rx_id_list_size =
256						sizeof(hdcp->auth.msg.hdcp2.rx_id_list);
257			else
258				hdcp->auth.msg.hdcp2.rx_id_list_size =
259					get_hdmi_rxstatus_msg_size(hdcp->auth.msg.hdcp2.rxstatus);
260		}
261out:
262	return (*status == MOD_HDCP_STATUS_SUCCESS);
263}
264
265static enum mod_hdcp_status known_hdcp2_capable_rx(struct mod_hdcp *hdcp,
266		struct mod_hdcp_event_context *event_ctx,
267		struct mod_hdcp_transition_input_hdcp2 *input)
268{
269	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
270
271	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
272		event_ctx->unexpected_event = 1;
273		goto out;
274	}
275
276	if (!mod_hdcp_execute_and_set(mod_hdcp_read_hdcp2version,
277			&input->hdcp2version_read, &status,
278			hdcp, "hdcp2version_read"))
279		goto out;
280	if (!mod_hdcp_execute_and_set(check_hdcp2_capable,
281			&input->hdcp2_capable_check, &status,
282			hdcp, "hdcp2_capable"))
283		goto out;
284out:
285	return status;
286}
287
288static enum mod_hdcp_status send_ake_init(struct mod_hdcp *hdcp,
289		struct mod_hdcp_event_context *event_ctx,
290		struct mod_hdcp_transition_input_hdcp2 *input)
291{
292	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
293
294	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
295		event_ctx->unexpected_event = 1;
296		goto out;
297	}
298
299	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_create_session,
300			&input->create_session, &status,
301			hdcp, "create_session"))
302		goto out;
303	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_prepare_ake_init,
304			&input->ake_init_prepare, &status,
305			hdcp, "ake_init_prepare"))
306		goto out;
307	if (!mod_hdcp_execute_and_set(mod_hdcp_write_ake_init,
308			&input->ake_init_write, &status,
309			hdcp, "ake_init_write"))
310		goto out;
311out:
312	return status;
313}
314
315static enum mod_hdcp_status validate_ake_cert(struct mod_hdcp *hdcp,
316		struct mod_hdcp_event_context *event_ctx,
317		struct mod_hdcp_transition_input_hdcp2 *input)
318{
319	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
320
321
322	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
323			event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
324		event_ctx->unexpected_event = 1;
325		goto out;
326	}
327
328	if (is_hdmi_dvi_sl_hdcp(hdcp))
329		if (!mod_hdcp_execute_and_set(check_ake_cert_available,
330				&input->ake_cert_available, &status,
331				hdcp, "ake_cert_available"))
332			goto out;
333	if (!mod_hdcp_execute_and_set(mod_hdcp_read_ake_cert,
334			&input->ake_cert_read, &status,
335			hdcp, "ake_cert_read"))
336		goto out;
337	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_validate_ake_cert,
338			&input->ake_cert_validation, &status,
339			hdcp, "ake_cert_validation"))
340		goto out;
341out:
342	return status;
343}
344
345static enum mod_hdcp_status send_no_stored_km(struct mod_hdcp *hdcp,
346		struct mod_hdcp_event_context *event_ctx,
347		struct mod_hdcp_transition_input_hdcp2 *input)
348{
349	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
350
351	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
352		event_ctx->unexpected_event = 1;
353		goto out;
354	}
355
356	if (!mod_hdcp_execute_and_set(mod_hdcp_write_no_stored_km,
357			&input->no_stored_km_write, &status,
358			hdcp, "no_stored_km_write"))
359		goto out;
360out:
361	return status;
362}
363
364static enum mod_hdcp_status read_h_prime(struct mod_hdcp *hdcp,
365		struct mod_hdcp_event_context *event_ctx,
366		struct mod_hdcp_transition_input_hdcp2 *input)
367{
368	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
369
370	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
371			event_ctx->event != MOD_HDCP_EVENT_CPIRQ &&
372			event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
373		event_ctx->unexpected_event = 1;
374		goto out;
375	}
376
377	if (!mod_hdcp_execute_and_set(check_h_prime_available,
378			&input->h_prime_available, &status,
379			hdcp, "h_prime_available"))
380		goto out;
381
382	if (!mod_hdcp_execute_and_set(mod_hdcp_read_h_prime,
383			&input->h_prime_read, &status,
384			hdcp, "h_prime_read"))
385		goto out;
386out:
387	return status;
388}
389
390static enum mod_hdcp_status read_pairing_info_and_validate_h_prime(
391		struct mod_hdcp *hdcp,
392		struct mod_hdcp_event_context *event_ctx,
393		struct mod_hdcp_transition_input_hdcp2 *input)
394{
395	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
396
397	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
398			event_ctx->event != MOD_HDCP_EVENT_CPIRQ &&
399			event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
400		event_ctx->unexpected_event = 1;
401		goto out;
402	}
403
404	if (!mod_hdcp_execute_and_set(check_pairing_info_available,
405			&input->pairing_available, &status,
406			hdcp, "pairing_available"))
407		goto out;
408	if (!mod_hdcp_execute_and_set(mod_hdcp_read_pairing_info,
409			&input->pairing_info_read, &status,
410			hdcp, "pairing_info_read"))
411		goto out;
412	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_validate_h_prime,
413			&input->h_prime_validation, &status,
414			hdcp, "h_prime_validation"))
415		goto out;
416out:
417	return status;
418}
419
420static enum mod_hdcp_status send_stored_km(struct mod_hdcp *hdcp,
421		struct mod_hdcp_event_context *event_ctx,
422		struct mod_hdcp_transition_input_hdcp2 *input)
423{
424	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
425
426	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
427		event_ctx->unexpected_event = 1;
428		goto out;
429	}
430
431	if (!mod_hdcp_execute_and_set(mod_hdcp_write_stored_km,
432			&input->stored_km_write, &status,
433			hdcp, "stored_km_write"))
434		goto out;
435out:
436	return status;
437}
438
439static enum mod_hdcp_status validate_h_prime(struct mod_hdcp *hdcp,
440		struct mod_hdcp_event_context *event_ctx,
441		struct mod_hdcp_transition_input_hdcp2 *input)
442{
443	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
444
445	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
446			event_ctx->event != MOD_HDCP_EVENT_CPIRQ &&
447			event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
448		event_ctx->unexpected_event = 1;
449		goto out;
450	}
451
452	if (!mod_hdcp_execute_and_set(check_h_prime_available,
453			&input->h_prime_available, &status,
454			hdcp, "h_prime_available"))
455		goto out;
456	if (!mod_hdcp_execute_and_set(mod_hdcp_read_h_prime,
457			&input->h_prime_read, &status,
458			hdcp, "h_prime_read"))
459		goto out;
460	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_validate_h_prime,
461			&input->h_prime_validation, &status,
462			hdcp, "h_prime_validation"))
463		goto out;
464out:
465	return status;
466}
467
468static enum mod_hdcp_status locality_check(struct mod_hdcp *hdcp,
469		struct mod_hdcp_event_context *event_ctx,
470		struct mod_hdcp_transition_input_hdcp2 *input)
471{
472	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
473
474	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
475		event_ctx->unexpected_event = 1;
476		goto out;
477	}
478
479	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_prepare_lc_init,
480			&input->lc_init_prepare, &status,
481			hdcp, "lc_init_prepare"))
482		goto out;
483
484	if (hdcp->connection.link.adjust.hdcp2.use_fw_locality_check) {
485		if (!mod_hdcp_execute_and_set(mod_hdcp_write_poll_read_lc_fw,
486				&input->l_prime_combo_read, &status,
487				hdcp, "l_prime_combo_read"))
488			goto out;
489	} else {
490		if (!mod_hdcp_execute_and_set(mod_hdcp_write_lc_init,
491				&input->lc_init_write, &status,
492				hdcp, "lc_init_write"))
493			goto out;
494		if (is_dp_hdcp(hdcp))
495			msleep(16);
496		else
497			if (!mod_hdcp_execute_and_set(poll_l_prime_available,
498					&input->l_prime_available_poll, &status,
499					hdcp, "l_prime_available_poll"))
500				goto out;
501		if (!mod_hdcp_execute_and_set(mod_hdcp_read_l_prime,
502				&input->l_prime_read, &status,
503				hdcp, "l_prime_read"))
504			goto out;
505	}
506
507	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_validate_l_prime,
508			&input->l_prime_validation, &status,
509			hdcp, "l_prime_validation"))
510		goto out;
511out:
512	return status;
513}
514
515static enum mod_hdcp_status exchange_ks_and_test_for_repeater(struct mod_hdcp *hdcp,
516		struct mod_hdcp_event_context *event_ctx,
517		struct mod_hdcp_transition_input_hdcp2 *input)
518{
519	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
520
521	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
522		event_ctx->unexpected_event = 1;
523		goto out;
524	}
525
526	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_prepare_eks,
527			&input->eks_prepare, &status,
528			hdcp, "eks_prepare"))
529		goto out;
530	if (!mod_hdcp_execute_and_set(mod_hdcp_write_eks,
531			&input->eks_write, &status,
532			hdcp, "eks_write"))
533		goto out;
534out:
535	return status;
536}
537
538static enum mod_hdcp_status enable_encryption(struct mod_hdcp *hdcp,
539		struct mod_hdcp_event_context *event_ctx,
540		struct mod_hdcp_transition_input_hdcp2 *input)
541{
542	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
543
544	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
545			event_ctx->event != MOD_HDCP_EVENT_CPIRQ) {
546		event_ctx->unexpected_event = 1;
547		goto out;
548	}
549	if (event_ctx->event == MOD_HDCP_EVENT_CPIRQ) {
550		process_rxstatus(hdcp, event_ctx, input, &status);
551		goto out;
552	}
553
554	if (is_hdmi_dvi_sl_hdcp(hdcp)) {
555		if (!process_rxstatus(hdcp, event_ctx, input, &status))
556			goto out;
557		if (event_ctx->rx_id_list_ready)
558			goto out;
559	}
560	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_enable_encryption,
561			&input->enable_encryption, &status,
562			hdcp, "enable_encryption"))
563		goto out;
564	if (is_dp_mst_hdcp(hdcp)) {
565		if (!mod_hdcp_execute_and_set(
566				mod_hdcp_hdcp2_enable_dp_stream_encryption,
567				&input->stream_encryption_dp, &status,
568				hdcp, "stream_encryption_dp"))
569			goto out;
570	}
571out:
572	return status;
573}
574
575static enum mod_hdcp_status authenticated(struct mod_hdcp *hdcp,
576		struct mod_hdcp_event_context *event_ctx,
577		struct mod_hdcp_transition_input_hdcp2 *input)
578{
579	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
580
581	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
582			event_ctx->event != MOD_HDCP_EVENT_CPIRQ) {
583		event_ctx->unexpected_event = 1;
584		goto out;
585	}
586
587	process_rxstatus(hdcp, event_ctx, input, &status);
588out:
589	return status;
590}
591
592static enum mod_hdcp_status wait_for_rx_id_list(struct mod_hdcp *hdcp,
593		struct mod_hdcp_event_context *event_ctx,
594		struct mod_hdcp_transition_input_hdcp2 *input)
595{
596	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
597
598	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
599			event_ctx->event != MOD_HDCP_EVENT_CPIRQ &&
600			event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
601		event_ctx->unexpected_event = 1;
602		goto out;
603	}
604
605	if (!process_rxstatus(hdcp, event_ctx, input, &status))
606		goto out;
607	if (!event_ctx->rx_id_list_ready) {
608		status = MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_NOT_READY;
609		goto out;
610	}
611out:
612	return status;
613}
614
615static enum mod_hdcp_status verify_rx_id_list_and_send_ack(struct mod_hdcp *hdcp,
616		struct mod_hdcp_event_context *event_ctx,
617		struct mod_hdcp_transition_input_hdcp2 *input)
618{
619	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
620
621	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
622			event_ctx->event != MOD_HDCP_EVENT_CPIRQ) {
623		event_ctx->unexpected_event = 1;
624		goto out;
625	}
626	if (event_ctx->event == MOD_HDCP_EVENT_CPIRQ) {
627		process_rxstatus(hdcp, event_ctx, input, &status);
628		goto out;
629	}
630
631	if (!mod_hdcp_execute_and_set(mod_hdcp_read_rx_id_list,
632			&input->rx_id_list_read,
633			&status, hdcp, "receiver_id_list_read"))
634		goto out;
635	if (!mod_hdcp_execute_and_set(check_device_count,
636			&input->device_count_check,
637			&status, hdcp, "device_count_check"))
638		goto out;
639	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_validate_rx_id_list,
640			&input->rx_id_list_validation,
641			&status, hdcp, "rx_id_list_validation"))
642		goto out;
643	if (!mod_hdcp_execute_and_set(mod_hdcp_write_repeater_auth_ack,
644			&input->repeater_auth_ack_write,
645			&status, hdcp, "repeater_auth_ack_write"))
646		goto out;
647out:
648	return status;
649}
650
651static enum mod_hdcp_status send_stream_management(struct mod_hdcp *hdcp,
652		struct mod_hdcp_event_context *event_ctx,
653		struct mod_hdcp_transition_input_hdcp2 *input)
654{
655	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
656
657	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
658			event_ctx->event != MOD_HDCP_EVENT_CPIRQ) {
659		event_ctx->unexpected_event = 1;
660		goto out;
661	}
662	if (event_ctx->event == MOD_HDCP_EVENT_CPIRQ) {
663		process_rxstatus(hdcp, event_ctx, input, &status);
664		goto out;
665	}
666
667	if (is_hdmi_dvi_sl_hdcp(hdcp)) {
668		if (!process_rxstatus(hdcp, event_ctx, input, &status))
669			goto out;
670		if (event_ctx->rx_id_list_ready)
671			goto out;
672	}
673	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_prepare_stream_management,
674			&input->prepare_stream_manage,
675			&status, hdcp, "prepare_stream_manage"))
676		goto out;
677
678	if (!mod_hdcp_execute_and_set(mod_hdcp_write_stream_manage,
679			&input->stream_manage_write,
680			&status, hdcp, "stream_manage_write"))
681		goto out;
682out:
683	return status;
684}
685
686static enum mod_hdcp_status validate_stream_ready(struct mod_hdcp *hdcp,
687		struct mod_hdcp_event_context *event_ctx,
688		struct mod_hdcp_transition_input_hdcp2 *input)
689{
690	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
691
692	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
693			event_ctx->event != MOD_HDCP_EVENT_CPIRQ &&
694			event_ctx->event != MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
695		event_ctx->unexpected_event = 1;
696		goto out;
697	}
698	if (event_ctx->event == MOD_HDCP_EVENT_CPIRQ) {
699		process_rxstatus(hdcp, event_ctx, input, &status);
700		goto out;
701	}
702
703	if (is_hdmi_dvi_sl_hdcp(hdcp)) {
704		if (!process_rxstatus(hdcp, event_ctx, input, &status))
705			goto out;
706		if (event_ctx->rx_id_list_ready)
707			goto out;
708	}
709	if (is_hdmi_dvi_sl_hdcp(hdcp))
710		if (!mod_hdcp_execute_and_set(check_stream_ready_available,
711				&input->stream_ready_available,
712				&status, hdcp, "stream_ready_available"))
713			goto out;
714	if (!mod_hdcp_execute_and_set(mod_hdcp_read_stream_ready,
715			&input->stream_ready_read,
716			&status, hdcp, "stream_ready_read"))
717		goto out;
718	if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp2_validate_stream_ready,
719			&input->stream_ready_validation,
720			&status, hdcp, "stream_ready_validation"))
721		goto out;
722
723out:
724	return status;
725}
726
727static enum mod_hdcp_status determine_rx_hdcp_capable_dp(struct mod_hdcp *hdcp,
728		struct mod_hdcp_event_context *event_ctx,
729		struct mod_hdcp_transition_input_hdcp2 *input)
730{
731	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
732
733	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK) {
734		event_ctx->unexpected_event = 1;
735		goto out;
736	}
737
738	if (!mod_hdcp_execute_and_set(mod_hdcp_read_rxcaps,
739			&input->rx_caps_read_dp,
740			&status, hdcp, "rx_caps_read_dp"))
741		goto out;
742	if (!mod_hdcp_execute_and_set(check_hdcp2_capable,
743			&input->hdcp2_capable_check, &status,
744			hdcp, "hdcp2_capable_check"))
745		goto out;
746out:
747	return status;
748}
749
750static enum mod_hdcp_status send_content_stream_type_dp(struct mod_hdcp *hdcp,
751		struct mod_hdcp_event_context *event_ctx,
752		struct mod_hdcp_transition_input_hdcp2 *input)
753{
754	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
755
756	if (event_ctx->event != MOD_HDCP_EVENT_CALLBACK &&
757			event_ctx->event != MOD_HDCP_EVENT_CPIRQ) {
758		event_ctx->unexpected_event = 1;
759		goto out;
760	}
761
762	if (!process_rxstatus(hdcp, event_ctx, input, &status))
763		goto out;
764	if (!mod_hdcp_execute_and_set(mod_hdcp_write_content_type,
765			&input->content_stream_type_write, &status,
766			hdcp, "content_stream_type_write"))
767		goto out;
768out:
769	return status;
770}
771
772enum mod_hdcp_status mod_hdcp_hdcp2_execution(struct mod_hdcp *hdcp,
773	struct mod_hdcp_event_context *event_ctx,
774	struct mod_hdcp_transition_input_hdcp2 *input)
775{
776	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
777
778	switch (current_state(hdcp)) {
779	case H2_A0_KNOWN_HDCP2_CAPABLE_RX:
780		status = known_hdcp2_capable_rx(hdcp, event_ctx, input);
781		break;
782	case H2_A1_SEND_AKE_INIT:
783		status = send_ake_init(hdcp, event_ctx, input);
784		break;
785	case H2_A1_VALIDATE_AKE_CERT:
786		status = validate_ake_cert(hdcp, event_ctx, input);
787		break;
788	case H2_A1_SEND_NO_STORED_KM:
789		status = send_no_stored_km(hdcp, event_ctx, input);
790		break;
791	case H2_A1_READ_H_PRIME:
792		status = read_h_prime(hdcp, event_ctx, input);
793		break;
794	case H2_A1_READ_PAIRING_INFO_AND_VALIDATE_H_PRIME:
795		status = read_pairing_info_and_validate_h_prime(hdcp,
796				event_ctx, input);
797		break;
798	case H2_A1_SEND_STORED_KM:
799		status = send_stored_km(hdcp, event_ctx, input);
800		break;
801	case H2_A1_VALIDATE_H_PRIME:
802		status = validate_h_prime(hdcp, event_ctx, input);
803		break;
804	case H2_A2_LOCALITY_CHECK:
805		status = locality_check(hdcp, event_ctx, input);
806		break;
807	case H2_A3_EXCHANGE_KS_AND_TEST_FOR_REPEATER:
808		status = exchange_ks_and_test_for_repeater(hdcp, event_ctx, input);
809		break;
810	case H2_ENABLE_ENCRYPTION:
811		status = enable_encryption(hdcp, event_ctx, input);
812		break;
813	case H2_A5_AUTHENTICATED:
814		status = authenticated(hdcp, event_ctx, input);
815		break;
816	case H2_A6_WAIT_FOR_RX_ID_LIST:
817		status = wait_for_rx_id_list(hdcp, event_ctx, input);
818		break;
819	case H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK:
820		status = verify_rx_id_list_and_send_ack(hdcp, event_ctx, input);
821		break;
822	case H2_A9_SEND_STREAM_MANAGEMENT:
823		status = send_stream_management(hdcp, event_ctx, input);
824		break;
825	case H2_A9_VALIDATE_STREAM_READY:
826		status = validate_stream_ready(hdcp, event_ctx, input);
827		break;
828	default:
829		status = MOD_HDCP_STATUS_INVALID_STATE;
830		break;
831	}
832
833	return status;
834}
835
836enum mod_hdcp_status mod_hdcp_hdcp2_dp_execution(struct mod_hdcp *hdcp,
837	struct mod_hdcp_event_context *event_ctx,
838	struct mod_hdcp_transition_input_hdcp2 *input)
839{
840	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
841
842	switch (current_state(hdcp)) {
843	case D2_A0_DETERMINE_RX_HDCP_CAPABLE:
844		status = determine_rx_hdcp_capable_dp(hdcp, event_ctx, input);
845		break;
846	case D2_A1_SEND_AKE_INIT:
847		status = send_ake_init(hdcp, event_ctx, input);
848		break;
849	case D2_A1_VALIDATE_AKE_CERT:
850		status = validate_ake_cert(hdcp, event_ctx, input);
851		break;
852	case D2_A1_SEND_NO_STORED_KM:
853		status = send_no_stored_km(hdcp, event_ctx, input);
854		break;
855	case D2_A1_READ_H_PRIME:
856		status = read_h_prime(hdcp, event_ctx, input);
857		break;
858	case D2_A1_READ_PAIRING_INFO_AND_VALIDATE_H_PRIME:
859		status = read_pairing_info_and_validate_h_prime(hdcp,
860				event_ctx, input);
861		break;
862	case D2_A1_SEND_STORED_KM:
863		status = send_stored_km(hdcp, event_ctx, input);
864		break;
865	case D2_A1_VALIDATE_H_PRIME:
866		status = validate_h_prime(hdcp, event_ctx, input);
867		break;
868	case D2_A2_LOCALITY_CHECK:
869		status = locality_check(hdcp, event_ctx, input);
870		break;
871	case D2_A34_EXCHANGE_KS_AND_TEST_FOR_REPEATER:
872		status = exchange_ks_and_test_for_repeater(hdcp,
873				event_ctx, input);
874		break;
875	case D2_SEND_CONTENT_STREAM_TYPE:
876		status = send_content_stream_type_dp(hdcp, event_ctx, input);
877		break;
878	case D2_ENABLE_ENCRYPTION:
879		status = enable_encryption(hdcp, event_ctx, input);
880		break;
881	case D2_A5_AUTHENTICATED:
882		status = authenticated(hdcp, event_ctx, input);
883		break;
884	case D2_A6_WAIT_FOR_RX_ID_LIST:
885		status = wait_for_rx_id_list(hdcp, event_ctx, input);
886		break;
887	case D2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK:
888		status = verify_rx_id_list_and_send_ack(hdcp, event_ctx, input);
889		break;
890	case D2_A9_SEND_STREAM_MANAGEMENT:
891		status = send_stream_management(hdcp, event_ctx, input);
892		break;
893	case D2_A9_VALIDATE_STREAM_READY:
894		status = validate_stream_ready(hdcp, event_ctx, input);
895		break;
896	default:
897		status = MOD_HDCP_STATUS_INVALID_STATE;
898		break;
899	}
900
901	return status;
902}
~/ Read-only file preview.