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 /* 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 382 enum 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 } 705