linux/drivers/gpu/drm/amd/display/modules/hdcp/hdcp2_transition.c
<<
>>
Prefs
   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
  28enum mod_hdcp_status mod_hdcp_hdcp2_transition(struct mod_hdcp *hdcp,
  29                struct mod_hdcp_event_context *event_ctx,
  30                struct mod_hdcp_transition_input_hdcp2 *input,
  31                struct mod_hdcp_output *output)
  32{
  33        enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
  34        struct mod_hdcp_connection *conn = &hdcp->connection;
  35        struct mod_hdcp_link_adjustment *adjust = &hdcp->connection.link.adjust;
  36
  37        switch (current_state(hdcp)) {
  38        case H2_A0_KNOWN_HDCP2_CAPABLE_RX:
  39                if (input->hdcp2version_read != PASS ||
  40                                input->hdcp2_capable_check != PASS) {
  41                        adjust->hdcp2.disable = 1;
  42                        callback_in_ms(0, output);
  43                        set_state_id(hdcp, output, HDCP_INITIALIZED);
  44                } else {
  45                        callback_in_ms(0, output);
  46                        set_state_id(hdcp, output, H2_A1_SEND_AKE_INIT);
  47                }
  48                break;
  49        case H2_A1_SEND_AKE_INIT:
  50                if (input->create_session != PASS ||
  51                                input->ake_init_prepare != PASS) {
  52                        /* out of sync with psp state */
  53                        adjust->hdcp2.disable = 1;
  54                        fail_and_restart_in_ms(0, &status, output);
  55                        break;
  56                } else if (input->ake_init_write != PASS) {
  57                        fail_and_restart_in_ms(0, &status, output);
  58                        break;
  59                }
  60                set_watchdog_in_ms(hdcp, 100, output);
  61                callback_in_ms(0, output);
  62                set_state_id(hdcp, output, H2_A1_VALIDATE_AKE_CERT);
  63                break;
  64        case H2_A1_VALIDATE_AKE_CERT:
  65                if (input->ake_cert_available != PASS) {
  66                        if (event_ctx->event ==
  67                                        MOD_HDCP_EVENT_WATCHDOG_TIMEOUT) {
  68                                /* 1A-08: consider ake timeout a failure */
  69                                /* some hdmi receivers are not ready for 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                HDCP_FULL_DDC_TRACE(hdcp);
 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
 369enum mod_hdcp_status mod_hdcp_hdcp2_dp_transition(struct mod_hdcp *hdcp,
 370                struct mod_hdcp_event_context *event_ctx,
 371                struct mod_hdcp_transition_input_hdcp2 *input,
 372                struct mod_hdcp_output *output)
 373{
 374        enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
 375        struct mod_hdcp_connection *conn = &hdcp->connection;
 376        struct mod_hdcp_link_adjustment *adjust = &hdcp->connection.link.adjust;
 377
 378        switch (current_state(hdcp)) {
 379        case D2_A0_DETERMINE_RX_HDCP_CAPABLE:
 380                if (input->rx_caps_read_dp != PASS ||
 381                                input->hdcp2_capable_check != PASS) {
 382                        adjust->hdcp2.disable = 1;
 383                        callback_in_ms(0, output);
 384                        set_state_id(hdcp, output, HDCP_INITIALIZED);
 385                } else {
 386                        callback_in_ms(0, output);
 387                        set_state_id(hdcp, output, D2_A1_SEND_AKE_INIT);
 388                }
 389                break;
 390        case D2_A1_SEND_AKE_INIT:
 391                if (input->create_session != PASS ||
 392                                input->ake_init_prepare != PASS) {
 393                        /* out of sync with psp state */
 394                        adjust->hdcp2.disable = 1;
 395                        fail_and_restart_in_ms(0, &status, output);
 396                        break;
 397                } else if (input->ake_init_write != PASS) {
 398                        /* possibly display not ready */
 399                        fail_and_restart_in_ms(0, &status, output);
 400                        break;
 401                }
 402                callback_in_ms(100, output);
 403                set_state_id(hdcp, output, D2_A1_VALIDATE_AKE_CERT);
 404                break;
 405        case D2_A1_VALIDATE_AKE_CERT:
 406                if (input->ake_cert_read != PASS ||
 407                                input->ake_cert_validation != PASS) {
 408                        /*
 409                         * 1A-08: consider invalid ake cert a 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(0, 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                HDCP_FULL_DDC_TRACE(hdcp);
 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