Merge tag 'drm-misc-next-fixes-2021-09-09' of git://anongit.freedesktop.org/drm/drm...
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / display / modules / hdcp / hdcp2_transition.c
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(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                 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 }