Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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}