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