File Index
Files and directories
Sign in
FILE

hdcp2_transition.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_transition.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 "hdcp.h"
 27
 28enum mod_hdcp_status mod_hdcp_hdcp2_transition(struct mod_hdcp *hdcp,
 29		struct mod_hdcp_event_context *event_ctx,
 30		struct mod_hdcp_transition_input_hdcp2 *input,
 31		struct mod_hdcp_output *output)
 32{
 33	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
 34	struct mod_hdcp_connection *conn = &hdcp->connection;
 35	struct mod_hdcp_link_adjustment *adjust = &hdcp->connection.link.adjust;
 36
 37	switch (current_state(hdcp)) {
 38	case H2_A0_KNOWN_HDCP2_CAPABLE_RX:
 39		if (input->hdcp2version_read != PASS ||
 40				input->hdcp2_capable_check != PASS) {
 41			adjust->hdcp2.disable = 1;
 42			callback_in_ms(0, output);
 43			set_state_id(hdcp, output, HDCP_INITIALIZED);
 44		} else {
 45			callback_in_ms(0, output);
 46			set_state_id(hdcp, output, H2_A1_SEND_AKE_INIT);
 47		}
 48		break;
 49	case H2_A1_SEND_AKE_INIT:
 50		if (input->create_session != PASS ||
 51				input->ake_init_prepare != PASS) {
 52			/* out of sync with psp state */
 53			adjust->hdcp2.disable = 1;
 54			fail_and_restart_in_ms(0, &status, output);
 55			break;
 56		} else if (input->ake_init_write != PASS) {
 57			fail_and_restart_in_ms(0, &status, output);
 58			break;
 59		}
 60		set_watchdog_in_ms(hdcp, 100, output);
 61		callback_in_ms(0, output);
 62		set_state_id(hdcp, output, H2_A1_VALIDATE_AKE_CERT);
 63		break;
 64	case H2_A1_VALIDATE_AKE_CERT:
 65		if (input->ake_cert_available != PASS) {
 66			if (event_ctx->event ==
 67					MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
 68				/* 1A-08: consider ake timeout a failure */
 69				/* some hdmi receivers are not ready for HDCP
 70				 * immediately after video becomes active,
 71				 * delay 1s before retry on first HDCP message
 72				 * timeout.
 73				 */
 74				fail_and_restart_in_ms(1000, &status, output);
 75			} else {
 76				/* continue ake cert polling*/
 77				callback_in_ms(10, output);
 78				increment_stay_counter(hdcp);
 79			}
 80			break;
 81		} else if (input->ake_cert_read != PASS ||
 82				input->ake_cert_validation != PASS) {
 83			/*
 84			 * 1A-09: consider invalid ake cert a failure
 85			 * 1A-10: consider receiver id listed in SRM a failure
 86			 */
 87			fail_and_restart_in_ms(0, &status, output);
 88			break;
 89		}
 90		if (conn->is_km_stored &&
 91				!adjust->hdcp2.force_no_stored_km) {
 92			callback_in_ms(0, output);
 93			set_state_id(hdcp, output, H2_A1_SEND_STORED_KM);
 94		} else {
 95			callback_in_ms(0, output);
 96			set_state_id(hdcp, output, H2_A1_SEND_NO_STORED_KM);
 97		}
 98		break;
 99	case H2_A1_SEND_NO_STORED_KM:
100		if (input->no_stored_km_write != PASS) {
101			fail_and_restart_in_ms(0, &status, output);
102			break;
103		}
104		if (adjust->hdcp2.increase_h_prime_timeout)
105			set_watchdog_in_ms(hdcp, 2000, output);
106		else
107			set_watchdog_in_ms(hdcp, 1000, output);
108		callback_in_ms(0, output);
109		set_state_id(hdcp, output, H2_A1_READ_H_PRIME);
110		break;
111	case H2_A1_READ_H_PRIME:
112		if (input->h_prime_available != PASS) {
113			if (event_ctx->event ==
114					MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
115				/* 1A-11-3: consider h' timeout a failure */
116				fail_and_restart_in_ms(1000, &status, output);
117			} else {
118				/* continue h' polling */
119				callback_in_ms(100, output);
120				increment_stay_counter(hdcp);
121			}
122			break;
123		} else if (input->h_prime_read != PASS) {
124			fail_and_restart_in_ms(0, &status, output);
125			break;
126		}
127		set_watchdog_in_ms(hdcp, 200, output);
128		callback_in_ms(0, output);
129		set_state_id(hdcp, output, H2_A1_READ_PAIRING_INFO_AND_VALIDATE_H_PRIME);
130		break;
131	case H2_A1_READ_PAIRING_INFO_AND_VALIDATE_H_PRIME:
132		if (input->pairing_available != PASS) {
133			if (event_ctx->event ==
134					MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
135				/* 1A-12: consider pairing info timeout
136				 * a failure
137				 */
138				fail_and_restart_in_ms(0, &status, output);
139			} else {
140				/* continue pairing info polling */
141				callback_in_ms(20, output);
142				increment_stay_counter(hdcp);
143			}
144			break;
145		} else if (input->pairing_info_read != PASS ||
146				input->h_prime_validation != PASS) {
147			/* 1A-11-1: consider invalid h' a failure */
148			fail_and_restart_in_ms(0, &status, output);
149			break;
150		}
151		callback_in_ms(0, output);
152		set_state_id(hdcp, output, H2_A2_LOCALITY_CHECK);
153		break;
154	case H2_A1_SEND_STORED_KM:
155		if (input->stored_km_write != PASS) {
156			fail_and_restart_in_ms(0, &status, output);
157			break;
158		}
159		set_watchdog_in_ms(hdcp, 200, output);
160		callback_in_ms(0, output);
161		set_state_id(hdcp, output, H2_A1_VALIDATE_H_PRIME);
162		break;
163	case H2_A1_VALIDATE_H_PRIME:
164		if (input->h_prime_available != PASS) {
165			if (event_ctx->event ==
166					MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
167				/* 1A-11-2: consider h' timeout a failure */
168				fail_and_restart_in_ms(1000, &status, output);
169			} else {
170				/* continue h' polling */
171				callback_in_ms(20, output);
172				increment_stay_counter(hdcp);
173			}
174			break;
175		} else if (input->h_prime_read != PASS) {
176			fail_and_restart_in_ms(0, &status, output);
177			break;
178		} else if (input->h_prime_validation != PASS) {
179			/* 1A-11-1: consider invalid h' a failure */
180			adjust->hdcp2.force_no_stored_km = 1;
181			fail_and_restart_in_ms(0, &status, output);
182			break;
183		}
184		callback_in_ms(0, output);
185		set_state_id(hdcp, output, H2_A2_LOCALITY_CHECK);
186		break;
187	case H2_A2_LOCALITY_CHECK:
188		/* 1A-05: consider disconnection after LC init a failure */
189		if (hdcp->state.stay_count > 10 ||
190				input->lc_init_prepare != PASS) {
191			fail_and_restart_in_ms(0, &status, output);
192			break;
193		} else if (adjust->hdcp2.use_fw_locality_check &&
194				input->l_prime_combo_read != PASS) {
195			/* 1A-13-2: consider l' timeout a failure */
196			if (adjust->hdcp2.use_sw_locality_fallback) {
197				/* switch to software locality check */
198				adjust->hdcp2.use_fw_locality_check = 0;
199				callback_in_ms(0, output);
200				increment_stay_counter(hdcp);
201				break;
202			}
203			fail_and_restart_in_ms(0, &status, output);
204			break;
205		} else if (!adjust->hdcp2.use_fw_locality_check &&
206					(input->lc_init_write != PASS ||
207					input->l_prime_available_poll != PASS ||
208					input->l_prime_read != PASS)) {
209			/* 1A-13-2: consider l' timeout a failure */
210			fail_and_restart_in_ms(0, &status, output);
211			break;
212		} else if (input->l_prime_validation != PASS) {
213			/* 1A-13-1: consider invalid l' a failure */
214			callback_in_ms(0, output);
215			increment_stay_counter(hdcp);
216			break;
217		}
218		callback_in_ms(0, output);
219		set_state_id(hdcp, output, H2_A3_EXCHANGE_KS_AND_TEST_FOR_REPEATER);
220		break;
221	case H2_A3_EXCHANGE_KS_AND_TEST_FOR_REPEATER:
222		if (input->eks_prepare != PASS ||
223				input->eks_write != PASS) {
224			fail_and_restart_in_ms(0, &status, output);
225			break;
226		}
227		if (conn->is_repeater) {
228			set_watchdog_in_ms(hdcp, 3000, output);
229			callback_in_ms(0, output);
230			set_state_id(hdcp, output, H2_A6_WAIT_FOR_RX_ID_LIST);
231		} else {
232			/* some CTS equipment requires a delay GREATER than
233			 * 200 ms, so delay 210 ms instead of 200 ms
234			 */
235			callback_in_ms(210, output);
236			set_state_id(hdcp, output, H2_ENABLE_ENCRYPTION);
237		}
238		break;
239	case H2_ENABLE_ENCRYPTION:
240		if (input->rxstatus_read != PASS ||
241				input->reauth_request_check != PASS) {
242			/*
243			 * 1A-07: restart hdcp on REAUTH_REQ
244			 * 1B-08: restart hdcp on REAUTH_REQ
245			 */
246			fail_and_restart_in_ms(0, &status, output);
247			break;
248		} else if (event_ctx->rx_id_list_ready && conn->is_repeater) {
249			callback_in_ms(0, output);
250			set_state_id(hdcp, output, H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK);
251			break;
252		} else if (input->enable_encryption != PASS) {
253			fail_and_restart_in_ms(0, &status, output);
254			break;
255		}
256		callback_in_ms(0, output);
257		set_state_id(hdcp, output, H2_A5_AUTHENTICATED);
258		set_auth_complete(hdcp, output);
259		break;
260	case H2_A5_AUTHENTICATED:
261		if (input->rxstatus_read == FAIL ||
262				input->reauth_request_check == FAIL) {
263			fail_and_restart_in_ms(0, &status, output);
264			break;
265		} else if (event_ctx->rx_id_list_ready && conn->is_repeater) {
266			callback_in_ms(0, output);
267			set_state_id(hdcp, output, H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK);
268			break;
269		}
270		callback_in_ms(500, output);
271		increment_stay_counter(hdcp);
272		break;
273	case H2_A6_WAIT_FOR_RX_ID_LIST:
274		if (input->rxstatus_read != PASS ||
275				input->reauth_request_check != PASS) {
276			fail_and_restart_in_ms(0, &status, output);
277			break;
278		} else if (!event_ctx->rx_id_list_ready) {
279			if (event_ctx->event == MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
280				/* 1B-02: consider rx id list timeout a failure */
281				/* some CTS equipment's actual timeout
282				 * measurement is slightly greater than 3000 ms.
283				 * Delay 100 ms to ensure it is fully timeout
284				 * before re-authentication.
285				 */
286				fail_and_restart_in_ms(100, &status, output);
287			} else {
288				callback_in_ms(300, output);
289				increment_stay_counter(hdcp);
290			}
291			break;
292		}
293		callback_in_ms(0, output);
294		set_state_id(hdcp, output, H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK);
295		break;
296	case H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK:
297		if (input->rxstatus_read != PASS ||
298				input->reauth_request_check != PASS ||
299				input->rx_id_list_read != PASS ||
300				input->device_count_check != PASS ||
301				input->rx_id_list_validation != PASS ||
302				input->repeater_auth_ack_write != PASS) {
303			/* 1B-03: consider invalid v' a failure
304			 * 1B-04: consider MAX_DEVS_EXCEEDED a failure
305			 * 1B-05: consider MAX_CASCADE_EXCEEDED a failure
306			 * 1B-06: consider invalid seq_num_V a failure
307			 * 1B-09: consider seq_num_V rollover a failure
308			 */
309			fail_and_restart_in_ms(0, &status, output);
310			break;
311		}
312		callback_in_ms(0, output);
313		set_state_id(hdcp, output, H2_A9_SEND_STREAM_MANAGEMENT);
314		break;
315	case H2_A9_SEND_STREAM_MANAGEMENT:
316		if (input->rxstatus_read != PASS ||
317				input->reauth_request_check != PASS) {
318			fail_and_restart_in_ms(0, &status, output);
319			break;
320		} else if (event_ctx->rx_id_list_ready && conn->is_repeater) {
321			callback_in_ms(0, output);
322			set_state_id(hdcp, output, H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK);
323			break;
324		} else if (input->prepare_stream_manage != PASS ||
325				input->stream_manage_write != PASS) {
326			fail_and_restart_in_ms(0, &status, output);
327			break;
328		}
329		set_watchdog_in_ms(hdcp, 100, output);
330		callback_in_ms(0, output);
331		set_state_id(hdcp, output, H2_A9_VALIDATE_STREAM_READY);
332		break;
333	case H2_A9_VALIDATE_STREAM_READY:
334		if (input->rxstatus_read != PASS ||
335				input->reauth_request_check != PASS) {
336			fail_and_restart_in_ms(0, &status, output);
337			break;
338		} else if (event_ctx->rx_id_list_ready && conn->is_repeater) {
339			callback_in_ms(0, output);
340			set_state_id(hdcp, output, H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK);
341			break;
342		} else if (input->stream_ready_available != PASS) {
343			if (event_ctx->event == MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
344				/* 1B-10-2: restart content stream management on
345				 * stream ready timeout
346				 */
347				hdcp->auth.count.stream_management_retry_count++;
348				callback_in_ms(0, output);
349				set_state_id(hdcp, output, H2_A9_SEND_STREAM_MANAGEMENT);
350			} else {
351				callback_in_ms(10, output);
352				increment_stay_counter(hdcp);
353			}
354			break;
355		} else if (input->stream_ready_read != PASS ||
356				input->stream_ready_validation != PASS) {
357			/*
358			 * 1B-10-1: restart content stream management
359			 * on invalid M'
360			 */
361			if (hdcp->auth.count.stream_management_retry_count > 10) {
362				fail_and_restart_in_ms(0, &status, output);
363			} else {
364				hdcp->auth.count.stream_management_retry_count++;
365				callback_in_ms(0, output);
366				set_state_id(hdcp, output, H2_A9_SEND_STREAM_MANAGEMENT);
367			}
368			break;
369		}
370		callback_in_ms(200, output);
371		set_state_id(hdcp, output, H2_ENABLE_ENCRYPTION);
372		break;
373	default:
374		status = MOD_HDCP_STATUS_INVALID_STATE;
375		fail_and_restart_in_ms(0, &status, output);
376		break;
377	}
378
379	return status;
380}
381
382enum mod_hdcp_status mod_hdcp_hdcp2_dp_transition(struct mod_hdcp *hdcp,
383		struct mod_hdcp_event_context *event_ctx,
384		struct mod_hdcp_transition_input_hdcp2 *input,
385		struct mod_hdcp_output *output)
386{
387	enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
388	struct mod_hdcp_connection *conn = &hdcp->connection;
389	struct mod_hdcp_link_adjustment *adjust = &hdcp->connection.link.adjust;
390
391	switch (current_state(hdcp)) {
392	case D2_A0_DETERMINE_RX_HDCP_CAPABLE:
393		if (input->rx_caps_read_dp != PASS ||
394				input->hdcp2_capable_check != PASS) {
395			adjust->hdcp2.disable = 1;
396			callback_in_ms(0, output);
397			set_state_id(hdcp, output, HDCP_INITIALIZED);
398		} else {
399			callback_in_ms(0, output);
400			set_state_id(hdcp, output, D2_A1_SEND_AKE_INIT);
401		}
402		break;
403	case D2_A1_SEND_AKE_INIT:
404		if (input->create_session != PASS ||
405				input->ake_init_prepare != PASS) {
406			/* out of sync with psp state */
407			adjust->hdcp2.disable = 1;
408			fail_and_restart_in_ms(0, &status, output);
409			break;
410		} else if (input->ake_init_write != PASS) {
411			/* possibly display not ready */
412			fail_and_restart_in_ms(0, &status, output);
413			break;
414		}
415		callback_in_ms(100, output);
416		set_state_id(hdcp, output, D2_A1_VALIDATE_AKE_CERT);
417		break;
418	case D2_A1_VALIDATE_AKE_CERT:
419		if (input->ake_cert_read != PASS ||
420				input->ake_cert_validation != PASS) {
421			/*
422			 * 1A-08: consider invalid ake cert a failure
423			 * 1A-09: consider receiver id listed in SRM a failure
424			 */
425			fail_and_restart_in_ms(0, &status, output);
426			break;
427		}
428		if (conn->is_km_stored &&
429				!adjust->hdcp2.force_no_stored_km) {
430			callback_in_ms(0, output);
431			set_state_id(hdcp, output, D2_A1_SEND_STORED_KM);
432		} else {
433			callback_in_ms(0, output);
434			set_state_id(hdcp, output, D2_A1_SEND_NO_STORED_KM);
435		}
436		break;
437	case D2_A1_SEND_NO_STORED_KM:
438		if (input->no_stored_km_write != PASS) {
439			fail_and_restart_in_ms(0, &status, output);
440			break;
441		}
442		if (adjust->hdcp2.increase_h_prime_timeout)
443			set_watchdog_in_ms(hdcp, 2000, output);
444		else
445			set_watchdog_in_ms(hdcp, 1000, output);
446		set_state_id(hdcp, output, D2_A1_READ_H_PRIME);
447		break;
448	case D2_A1_READ_H_PRIME:
449		if (input->h_prime_available != PASS) {
450			if (event_ctx->event ==
451					MOD_HDCP_EVENT_WATCHDOG_TIMEOUT)
452				/* 1A-10-3: consider h' timeout a failure */
453				fail_and_restart_in_ms(1000, &status, output);
454			else
455				increment_stay_counter(hdcp);
456			break;
457		} else if (input->h_prime_read != PASS) {
458			fail_and_restart_in_ms(0, &status, output);
459			break;
460		}
461		set_watchdog_in_ms(hdcp, 200, output);
462		set_state_id(hdcp, output, D2_A1_READ_PAIRING_INFO_AND_VALIDATE_H_PRIME);
463		break;
464	case D2_A1_READ_PAIRING_INFO_AND_VALIDATE_H_PRIME:
465		if (input->pairing_available != PASS) {
466			if (event_ctx->event ==
467					MOD_HDCP_EVENT_WATCHDOG_TIMEOUT)
468				/*
469				 * 1A-11: consider pairing info timeout
470				 * a failure
471				 */
472				fail_and_restart_in_ms(0, &status, output);
473			else
474				increment_stay_counter(hdcp);
475			break;
476		} else if (input->pairing_info_read != PASS ||
477				input->h_prime_validation != PASS) {
478			/* 1A-10-1: consider invalid h' a failure */
479			fail_and_restart_in_ms(0, &status, output);
480			break;
481		}
482		callback_in_ms(0, output);
483		set_state_id(hdcp, output, D2_A2_LOCALITY_CHECK);
484		break;
485	case D2_A1_SEND_STORED_KM:
486		if (input->stored_km_write != PASS) {
487			fail_and_restart_in_ms(0, &status, output);
488			break;
489		}
490		set_watchdog_in_ms(hdcp, 200, output);
491		set_state_id(hdcp, output, D2_A1_VALIDATE_H_PRIME);
492		break;
493	case D2_A1_VALIDATE_H_PRIME:
494		if (input->h_prime_available != PASS) {
495			if (event_ctx->event ==
496					MOD_HDCP_EVENT_WATCHDOG_TIMEOUT)
497				/* 1A-10-2: consider h' timeout a failure */
498				fail_and_restart_in_ms(1000, &status, output);
499			else
500				increment_stay_counter(hdcp);
501			break;
502		} else if (input->h_prime_read != PASS) {
503			fail_and_restart_in_ms(0, &status, output);
504			break;
505		} else if (input->h_prime_validation != PASS) {
506			/* 1A-10-1: consider invalid h' a failure */
507			adjust->hdcp2.force_no_stored_km = 1;
508			fail_and_restart_in_ms(0, &status, output);
509			break;
510		}
511		callback_in_ms(0, output);
512		set_state_id(hdcp, output, D2_A2_LOCALITY_CHECK);
513		break;
514	case D2_A2_LOCALITY_CHECK:
515		if (hdcp->state.stay_count > 10 ||
516				input->lc_init_prepare != PASS) {
517			fail_and_restart_in_ms(0, &status, output);
518			break;
519		} else if (adjust->hdcp2.use_fw_locality_check &&
520				input->l_prime_combo_read != PASS) {
521			if (adjust->hdcp2.use_sw_locality_fallback) {
522				/* switch to software locality check */
523				adjust->hdcp2.use_fw_locality_check = 0;
524				callback_in_ms(0, output);
525				increment_stay_counter(hdcp);
526				break;
527			}
528			fail_and_restart_in_ms(0, &status, output);
529			break;
530		} else if (!adjust->hdcp2.use_fw_locality_check &&
531					(input->lc_init_write != PASS ||
532					input->l_prime_read != PASS)) {
533			fail_and_restart_in_ms(0, &status, output);
534			break;
535		} else if (input->l_prime_validation != PASS) {
536			/* 1A-12: consider invalid l' a failure */
537			callback_in_ms(0, output);
538			increment_stay_counter(hdcp);
539			break;
540		}
541		callback_in_ms(0, output);
542		set_state_id(hdcp, output, D2_A34_EXCHANGE_KS_AND_TEST_FOR_REPEATER);
543		break;
544	case D2_A34_EXCHANGE_KS_AND_TEST_FOR_REPEATER:
545		if (input->eks_prepare != PASS ||
546				input->eks_write != PASS) {
547			fail_and_restart_in_ms(0, &status, output);
548			break;
549		}
550		if (conn->is_repeater) {
551			set_watchdog_in_ms(hdcp, 3000, output);
552			set_state_id(hdcp, output, D2_A6_WAIT_FOR_RX_ID_LIST);
553		} else {
554			callback_in_ms(1, output);
555			set_state_id(hdcp, output, D2_SEND_CONTENT_STREAM_TYPE);
556		}
557		break;
558	case D2_SEND_CONTENT_STREAM_TYPE:
559		if (input->rxstatus_read != PASS ||
560				input->reauth_request_check != PASS ||
561				input->link_integrity_check_dp != PASS ||
562				input->content_stream_type_write != PASS) {
563			fail_and_restart_in_ms(0, &status, output);
564			break;
565		}
566		callback_in_ms(210, output);
567		set_state_id(hdcp, output, D2_ENABLE_ENCRYPTION);
568		break;
569	case D2_ENABLE_ENCRYPTION:
570		if (input->rxstatus_read != PASS ||
571				input->reauth_request_check != PASS ||
572				input->link_integrity_check_dp != PASS) {
573			/*
574			 * 1A-07: restart hdcp on REAUTH_REQ
575			 * 1B-08: restart hdcp on REAUTH_REQ
576			 */
577			fail_and_restart_in_ms(0, &status, output);
578			break;
579		} else if (event_ctx->rx_id_list_ready && conn->is_repeater) {
580			callback_in_ms(0, output);
581			set_state_id(hdcp, output, D2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK);
582			break;
583		} else if (input->enable_encryption != PASS ||
584				(is_dp_mst_hdcp(hdcp) && input->stream_encryption_dp != PASS)) {
585			fail_and_restart_in_ms(0, &status, output);
586			break;
587		}
588		set_state_id(hdcp, output, D2_A5_AUTHENTICATED);
589		set_auth_complete(hdcp, output);
590		break;
591	case D2_A5_AUTHENTICATED:
592		if (input->rxstatus_read == FAIL ||
593				input->reauth_request_check == FAIL) {
594			fail_and_restart_in_ms(100, &status, output);
595			break;
596		} else if (input->link_integrity_check_dp == FAIL) {
597			if (hdcp->connection.hdcp2_retry_count >= 1)
598				adjust->hdcp2.force_type = MOD_HDCP_FORCE_TYPE_0;
599			fail_and_restart_in_ms(0, &status, output);
600			break;
601		} else if (event_ctx->rx_id_list_ready && conn->is_repeater) {
602			callback_in_ms(0, output);
603			set_state_id(hdcp, output, D2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK);
604			break;
605		}
606		increment_stay_counter(hdcp);
607		break;
608	case D2_A6_WAIT_FOR_RX_ID_LIST:
609		if (input->rxstatus_read != PASS ||
610				input->reauth_request_check != PASS ||
611				input->link_integrity_check_dp != PASS) {
612			fail_and_restart_in_ms(0, &status, output);
613			break;
614		} else if (!event_ctx->rx_id_list_ready) {
615			if (event_ctx->event == MOD_HDCP_EVENT_WATCHDOG_TIMEOUT)
616				/* 1B-02: consider rx id list timeout a failure */
617				fail_and_restart_in_ms(0, &status, output);
618			else
619				increment_stay_counter(hdcp);
620			break;
621		}
622		callback_in_ms(0, output);
623		set_state_id(hdcp, output, D2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK);
624		break;
625	case D2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK:
626		if (input->rxstatus_read != PASS ||
627				input->reauth_request_check != PASS ||
628				input->link_integrity_check_dp != PASS ||
629				input->rx_id_list_read != PASS ||
630				input->device_count_check != PASS ||
631				input->rx_id_list_validation != PASS ||
632				input->repeater_auth_ack_write != PASS) {
633			/*
634			 * 1B-03: consider invalid v' a failure
635			 * 1B-04: consider MAX_DEVS_EXCEEDED a failure
636			 * 1B-05: consider MAX_CASCADE_EXCEEDED a failure
637			 * 1B-06: consider invalid seq_num_V a failure
638			 * 1B-09: consider seq_num_V rollover a failure
639			 */
640			fail_and_restart_in_ms(0, &status, output);
641			break;
642		}
643		callback_in_ms(0, output);
644		set_state_id(hdcp, output, D2_A9_SEND_STREAM_MANAGEMENT);
645		break;
646	case D2_A9_SEND_STREAM_MANAGEMENT:
647		if (input->rxstatus_read != PASS ||
648				input->reauth_request_check != PASS ||
649				input->link_integrity_check_dp != PASS) {
650			fail_and_restart_in_ms(0, &status, output);
651			break;
652		} else if (event_ctx->rx_id_list_ready) {
653			callback_in_ms(0, output);
654			set_state_id(hdcp, output, D2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK);
655			break;
656		} else if (input->prepare_stream_manage != PASS ||
657				input->stream_manage_write != PASS) {
658			if (event_ctx->event == MOD_HDCP_EVENT_CALLBACK)
659				fail_and_restart_in_ms(0, &status, output);
660			else
661				increment_stay_counter(hdcp);
662			break;
663		}
664		callback_in_ms(100, output);
665		set_state_id(hdcp, output, D2_A9_VALIDATE_STREAM_READY);
666		break;
667	case D2_A9_VALIDATE_STREAM_READY:
668		if (input->rxstatus_read != PASS ||
669				input->reauth_request_check != PASS ||
670				input->link_integrity_check_dp != PASS) {
671			fail_and_restart_in_ms(0, &status, output);
672			break;
673		} else if (event_ctx->rx_id_list_ready) {
674			callback_in_ms(0, output);
675			set_state_id(hdcp, output, D2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK);
676			break;
677		} else if (input->stream_ready_read != PASS ||
678				input->stream_ready_validation != PASS) {
679			/*
680			 * 1B-10-1: restart content stream management
681			 * on invalid M'
682			 * 1B-10-2: consider stream ready timeout a failure
683			 */
684			if (hdcp->auth.count.stream_management_retry_count > 10) {
685				fail_and_restart_in_ms(0, &status, output);
686			} else if (event_ctx->event == MOD_HDCP_EVENT_CALLBACK) {
687				hdcp->auth.count.stream_management_retry_count++;
688				callback_in_ms(0, output);
689				set_state_id(hdcp, output, D2_A9_SEND_STREAM_MANAGEMENT);
690			} else {
691				increment_stay_counter(hdcp);
692			}
693			break;
694		}
695		callback_in_ms(200, output);
696		set_state_id(hdcp, output, D2_ENABLE_ENCRYPTION);
697		break;
698	default:
699		status = MOD_HDCP_STATUS_INVALID_STATE;
700		fail_and_restart_in_ms(0, &status, output);
701		break;
702	}
703	return status;
704}
~/ Read-only file preview.