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 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 failure 195 * 1A-13-1: consider invalid l' a failure 196 * 1A-13-2: consider l' timeout a failure 197 */ 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 than 220 * 200 ms, so delay 210 ms instead of 200 ms 221 */ 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_REQ 231 * 1B-08: restart hdcp on REAUTH_REQ 232 */ 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 timeout 269 * measurement is slightly greater than 3000 ms. 270 * Delay 100 ms to ensure it is fully timeout 271 * 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 failure 291 * 1B-04: consider MAX_DEVS_EXCEEDED a failure 292 * 1B-05: consider MAX_CASCADE_EXCEEDED a failure 293 * 1B-06: consider invalid seq_num_V a failure 294 * 1B-09: consider seq_num_V rollover a failure 295 */ 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 on 332 * stream ready timeout 333 */ 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 management 346 * 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 369 enum 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 failure 410 * 1A-09: consider receiver id listed in SRM a failure 411 */ 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 else 432 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 else 442 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 timeout 457 * a failure 458 */ 459 fail_and_restart_in_ms(0, &status, output); 460 else 461 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 else 487 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_REQ 548 * 1B-08: restart hdcp on REAUTH_REQ 549 */ 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 else 592 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 failure 608 * 1B-04: consider MAX_DEVS_EXCEEDED a failure 609 * 1B-05: consider MAX_CASCADE_EXCEEDED a failure 610 * 1B-06: consider invalid seq_num_V a failure 611 * 1B-09: consider seq_num_V rollover a failure 612 */ 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 else 634 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 management 654 * on invalid M' 655 * 1B-10-2: consider stream ready timeout a failure 656 */ 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