xref: /linux/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_transition.c (revision face6a3615a649456eb4549f6d474221d877d604)
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 
28 enum 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 
382 enum 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 }
705