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