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