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

source code of linux/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_transition.c