678 lines · c
1/*2 * Copyright 2018 Advanced Micro Devices, Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * 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 OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 * Authors: AMD23 *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 HDCP70 * immediately after video becomes active,71 * delay 1s before retry on first HDCP message72 * 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 failure85 * 1A-10: consider receiver id listed in SRM a failure86 */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 else107 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 timeout136 * a failure137 */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 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 failure195 * 1A-13-1: consider invalid l' a failure196 * 1A-13-2: consider l' timeout a failure197 */198 fail_and_restart_in_ms(0, &status, output);199 break;200 } else if (input->l_prime_validation != PASS) {201 callback_in_ms(0, output);202 increment_stay_counter(hdcp);203 break;204 }205 callback_in_ms(0, output);206 set_state_id(hdcp, output, 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(0, &status, output);212 break;213 }214 if (conn->is_repeater) {215 set_watchdog_in_ms(hdcp, 3000, output);216 callback_in_ms(0, output);217 set_state_id(hdcp, output, H2_A6_WAIT_FOR_RX_ID_LIST);218 } else {219 /* some CTS equipment requires a delay GREATER than220 * 200 ms, so delay 210 ms instead of 200 ms221 */222 callback_in_ms(210, output);223 set_state_id(hdcp, output, 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_REQ231 * 1B-08: restart hdcp on REAUTH_REQ232 */233 fail_and_restart_in_ms(0, &status, output);234 break;235 } else if (event_ctx->rx_id_list_ready && conn->is_repeater) {236 callback_in_ms(0, output);237 set_state_id(hdcp, output, H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK);238 break;239 } else if (input->enable_encryption != PASS) {240 fail_and_restart_in_ms(0, &status, output);241 break;242 }243 callback_in_ms(0, output);244 set_state_id(hdcp, output, 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(0, &status, output);251 break;252 } else if (event_ctx->rx_id_list_ready && conn->is_repeater) {253 callback_in_ms(0, output);254 set_state_id(hdcp, output, H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK);255 break;256 }257 callback_in_ms(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(0, &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 timeout269 * measurement is slightly greater than 3000 ms.270 * Delay 100 ms to ensure it is fully timeout271 * before re-authentication.272 */273 fail_and_restart_in_ms(100, &status, output);274 } else {275 callback_in_ms(300, output);276 increment_stay_counter(hdcp);277 }278 break;279 }280 callback_in_ms(0, output);281 set_state_id(hdcp, output, 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 failure291 * 1B-04: consider MAX_DEVS_EXCEEDED a failure292 * 1B-05: consider MAX_CASCADE_EXCEEDED a failure293 * 1B-06: consider invalid seq_num_V a failure294 * 1B-09: consider seq_num_V rollover a failure295 */296 fail_and_restart_in_ms(0, &status, output);297 break;298 }299 callback_in_ms(0, output);300 set_state_id(hdcp, output, 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(0, &status, output);306 break;307 } else if (event_ctx->rx_id_list_ready && conn->is_repeater) {308 callback_in_ms(0, output);309 set_state_id(hdcp, output, 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(0, &status, output);314 break;315 }316 set_watchdog_in_ms(hdcp, 100, output);317 callback_in_ms(0, output);318 set_state_id(hdcp, output, 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(0, &status, output);324 break;325 } else if (event_ctx->rx_id_list_ready && conn->is_repeater) {326 callback_in_ms(0, output);327 set_state_id(hdcp, output, 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 on332 * stream ready timeout333 */334 hdcp->auth.count.stream_management_retry_count++;335 callback_in_ms(0, output);336 set_state_id(hdcp, output, H2_A9_SEND_STREAM_MANAGEMENT);337 } else {338 callback_in_ms(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 management346 * on invalid M'347 */348 if (hdcp->auth.count.stream_management_retry_count > 10) {349 fail_and_restart_in_ms(0, &status, output);350 } else {351 hdcp->auth.count.stream_management_retry_count++;352 callback_in_ms(0, output);353 set_state_id(hdcp, output, H2_A9_SEND_STREAM_MANAGEMENT);354 }355 break;356 }357 callback_in_ms(200, output);358 set_state_id(hdcp, output, H2_ENABLE_ENCRYPTION);359 break;360 default:361 status = MOD_HDCP_STATUS_INVALID_STATE;362 fail_and_restart_in_ms(0, &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(0, output);384 set_state_id(hdcp, output, HDCP_INITIALIZED);385 } else {386 callback_in_ms(0, output);387 set_state_id(hdcp, output, 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(0, &status, output);396 break;397 } else if (input->ake_init_write != PASS) {398 /* possibly display not ready */399 fail_and_restart_in_ms(0, &status, output);400 break;401 }402 callback_in_ms(100, output);403 set_state_id(hdcp, output, 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 failure410 * 1A-09: consider receiver id listed in SRM a failure411 */412 fail_and_restart_in_ms(0, &status, output);413 break;414 }415 if (conn->is_km_stored &&416 !adjust->hdcp2.force_no_stored_km) {417 callback_in_ms(0, output);418 set_state_id(hdcp, output, D2_A1_SEND_STORED_KM);419 } else {420 callback_in_ms(0, output);421 set_state_id(hdcp, output, 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(0, &status, output);427 break;428 }429 if (adjust->hdcp2.increase_h_prime_timeout)430 set_watchdog_in_ms(hdcp, 2000, output);431 else432 set_watchdog_in_ms(hdcp, 1000, output);433 set_state_id(hdcp, output, 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(1000, &status, output);441 else442 increment_stay_counter(hdcp);443 break;444 } else if (input->h_prime_read != PASS) {445 fail_and_restart_in_ms(0, &status, output);446 break;447 }448 set_watchdog_in_ms(hdcp, 200, output);449 set_state_id(hdcp, output, 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 timeout457 * a failure458 */459 fail_and_restart_in_ms(0, &status, output);460 else461 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(0, &status, output);467 break;468 }469 callback_in_ms(0, output);470 set_state_id(hdcp, output, 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(0, &status, output);475 break;476 }477 set_watchdog_in_ms(hdcp, 200, output);478 set_state_id(hdcp, output, 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(1000, &status, output);486 else487 increment_stay_counter(hdcp);488 break;489 } else if (input->h_prime_read != PASS) {490 fail_and_restart_in_ms(0, &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(0, &status, output);496 break;497 }498 callback_in_ms(0, output);499 set_state_id(hdcp, output, 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(0, &status, output);508 break;509 } else if (input->l_prime_validation != PASS) {510 callback_in_ms(0, output);511 increment_stay_counter(hdcp);512 break;513 }514 callback_in_ms(0, output);515 set_state_id(hdcp, output, 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(0, &status, output);521 break;522 }523 if (conn->is_repeater) {524 set_watchdog_in_ms(hdcp, 3000, output);525 set_state_id(hdcp, output, D2_A6_WAIT_FOR_RX_ID_LIST);526 } else {527 callback_in_ms(1, output);528 set_state_id(hdcp, output, 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(0, &status, output);537 break;538 }539 callback_in_ms(210, output);540 set_state_id(hdcp, output, 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_REQ548 * 1B-08: restart hdcp on REAUTH_REQ549 */550 fail_and_restart_in_ms(0, &status, output);551 break;552 } else if (event_ctx->rx_id_list_ready && conn->is_repeater) {553 callback_in_ms(0, output);554 set_state_id(hdcp, output, 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(0, &status, output);559 break;560 }561 set_state_id(hdcp, output, 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(100, &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(0, &status, output);573 break;574 } else if (event_ctx->rx_id_list_ready && conn->is_repeater) {575 callback_in_ms(0, output);576 set_state_id(hdcp, output, 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(0, &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(0, &status, output);591 else592 increment_stay_counter(hdcp);593 break;594 }595 callback_in_ms(0, output);596 set_state_id(hdcp, output, 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 failure608 * 1B-04: consider MAX_DEVS_EXCEEDED a failure609 * 1B-05: consider MAX_CASCADE_EXCEEDED a failure610 * 1B-06: consider invalid seq_num_V a failure611 * 1B-09: consider seq_num_V rollover a failure612 */613 fail_and_restart_in_ms(0, &status, output);614 break;615 }616 callback_in_ms(0, output);617 set_state_id(hdcp, output, 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(0, &status, output);624 break;625 } else if (event_ctx->rx_id_list_ready) {626 callback_in_ms(0, output);627 set_state_id(hdcp, output, 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(0, &status, output);633 else634 increment_stay_counter(hdcp);635 break;636 }637 callback_in_ms(100, output);638 set_state_id(hdcp, output, 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(0, &status, output);645 break;646 } else if (event_ctx->rx_id_list_ready) {647 callback_in_ms(0, output);648 set_state_id(hdcp, output, 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 management654 * on invalid M'655 * 1B-10-2: consider stream ready timeout a failure656 */657 if (hdcp->auth.count.stream_management_retry_count > 10) {658 fail_and_restart_in_ms(0, &status, output);659 } else if (event_ctx->event == MOD_HDCP_EVENT_CALLBACK) {660 hdcp->auth.count.stream_management_retry_count++;661 callback_in_ms(0, output);662 set_state_id(hdcp, output, D2_A9_SEND_STREAM_MANAGEMENT);663 } else {664 increment_stay_counter(hdcp);665 }666 break;667 }668 callback_in_ms(200, output);669 set_state_id(hdcp, output, D2_ENABLE_ENCRYPTION);670 break;671 default:672 status = MOD_HDCP_STATUS_INVALID_STATE;673 fail_and_restart_in_ms(0, &status, output);674 break;675 }676 return status;677}678