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