2 * Copyright 2019 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
28 static inline enum mod_hdcp_status
validate_bksv(struct mod_hdcp
*hdcp
)
33 memcpy(&n
, hdcp
->auth
.msg
.hdcp1
.bksv
, sizeof(uint64_t));
39 return (count
== 20) ? MOD_HDCP_STATUS_SUCCESS
:
40 MOD_HDCP_STATUS_HDCP1_INVALID_BKSV
;
43 static inline enum mod_hdcp_status
check_ksv_ready(struct mod_hdcp
*hdcp
)
46 return (hdcp
->auth
.msg
.hdcp1
.bstatus
& DP_BSTATUS_READY
) ?
47 MOD_HDCP_STATUS_SUCCESS
:
48 MOD_HDCP_STATUS_HDCP1_KSV_LIST_NOT_READY
;
49 return (hdcp
->auth
.msg
.hdcp1
.bcaps
& DRM_HDCP_DDC_BCAPS_KSV_FIFO_READY
) ?
50 MOD_HDCP_STATUS_SUCCESS
:
51 MOD_HDCP_STATUS_HDCP1_KSV_LIST_NOT_READY
;
54 static inline enum mod_hdcp_status
check_hdcp_capable_dp(struct mod_hdcp
*hdcp
)
56 return (hdcp
->auth
.msg
.hdcp1
.bcaps
& DP_BCAPS_HDCP_CAPABLE
) ?
57 MOD_HDCP_STATUS_SUCCESS
:
58 MOD_HDCP_STATUS_HDCP1_NOT_CAPABLE
;
61 static inline enum mod_hdcp_status
check_r0p_available_dp(struct mod_hdcp
*hdcp
)
63 enum mod_hdcp_status status
;
64 if (is_dp_hdcp(hdcp
)) {
65 status
= (hdcp
->auth
.msg
.hdcp1
.bstatus
&
66 DP_BSTATUS_R0_PRIME_READY
) ?
67 MOD_HDCP_STATUS_SUCCESS
:
68 MOD_HDCP_STATUS_HDCP1_R0_PRIME_PENDING
;
70 status
= MOD_HDCP_STATUS_INVALID_OPERATION
;
75 static inline enum mod_hdcp_status
check_link_integrity_dp(
76 struct mod_hdcp
*hdcp
)
78 return (hdcp
->auth
.msg
.hdcp1
.bstatus
&
79 DP_BSTATUS_LINK_FAILURE
) ?
80 MOD_HDCP_STATUS_HDCP1_LINK_INTEGRITY_FAILURE
:
81 MOD_HDCP_STATUS_SUCCESS
;
84 static inline enum mod_hdcp_status
check_no_reauthentication_request_dp(
85 struct mod_hdcp
*hdcp
)
87 return (hdcp
->auth
.msg
.hdcp1
.bstatus
& DP_BSTATUS_REAUTH_REQ
) ?
88 MOD_HDCP_STATUS_HDCP1_REAUTH_REQUEST_ISSUED
:
89 MOD_HDCP_STATUS_SUCCESS
;
92 static inline enum mod_hdcp_status
check_no_max_cascade(struct mod_hdcp
*hdcp
)
94 enum mod_hdcp_status status
;
97 status
= DRM_HDCP_MAX_CASCADE_EXCEEDED(hdcp
->auth
.msg
.hdcp1
.binfo_dp
>> 8)
98 ? MOD_HDCP_STATUS_HDCP1_MAX_CASCADE_EXCEEDED_FAILURE
99 : MOD_HDCP_STATUS_SUCCESS
;
101 status
= DRM_HDCP_MAX_CASCADE_EXCEEDED(hdcp
->auth
.msg
.hdcp1
.bstatus
>> 8)
102 ? MOD_HDCP_STATUS_HDCP1_MAX_CASCADE_EXCEEDED_FAILURE
103 : MOD_HDCP_STATUS_SUCCESS
;
107 static inline enum mod_hdcp_status
check_no_max_devs(struct mod_hdcp
*hdcp
)
109 enum mod_hdcp_status status
;
111 if (is_dp_hdcp(hdcp
))
112 status
= DRM_HDCP_MAX_DEVICE_EXCEEDED(hdcp
->auth
.msg
.hdcp1
.binfo_dp
) ?
113 MOD_HDCP_STATUS_HDCP1_MAX_DEVS_EXCEEDED_FAILURE
:
114 MOD_HDCP_STATUS_SUCCESS
;
116 status
= DRM_HDCP_MAX_DEVICE_EXCEEDED(hdcp
->auth
.msg
.hdcp1
.bstatus
) ?
117 MOD_HDCP_STATUS_HDCP1_MAX_DEVS_EXCEEDED_FAILURE
:
118 MOD_HDCP_STATUS_SUCCESS
;
122 static inline uint8_t get_device_count(struct mod_hdcp
*hdcp
)
124 return is_dp_hdcp(hdcp
) ?
125 DRM_HDCP_NUM_DOWNSTREAM(hdcp
->auth
.msg
.hdcp1
.binfo_dp
) :
126 DRM_HDCP_NUM_DOWNSTREAM(hdcp
->auth
.msg
.hdcp1
.bstatus
);
129 static inline enum mod_hdcp_status
check_device_count(struct mod_hdcp
*hdcp
)
131 /* device count must be greater than or equal to tracked hdcp displays */
132 return (get_device_count(hdcp
) < get_added_display_count(hdcp
)) ?
133 MOD_HDCP_STATUS_HDCP1_DEVICE_COUNT_MISMATCH_FAILURE
:
134 MOD_HDCP_STATUS_SUCCESS
;
137 static enum mod_hdcp_status
wait_for_active_rx(struct mod_hdcp
*hdcp
,
138 struct mod_hdcp_event_context
*event_ctx
,
139 struct mod_hdcp_transition_input_hdcp1
*input
)
141 enum mod_hdcp_status status
= MOD_HDCP_STATUS_SUCCESS
;
143 if (event_ctx
->event
!= MOD_HDCP_EVENT_CALLBACK
) {
144 event_ctx
->unexpected_event
= 1;
148 if (!mod_hdcp_execute_and_set(mod_hdcp_read_bksv
,
149 &input
->bksv_read
, &status
,
152 if (!mod_hdcp_execute_and_set(mod_hdcp_read_bcaps
,
153 &input
->bcaps_read
, &status
,
160 static enum mod_hdcp_status
exchange_ksvs(struct mod_hdcp
*hdcp
,
161 struct mod_hdcp_event_context
*event_ctx
,
162 struct mod_hdcp_transition_input_hdcp1
*input
)
164 enum mod_hdcp_status status
= MOD_HDCP_STATUS_SUCCESS
;
166 if (event_ctx
->event
!= MOD_HDCP_EVENT_CALLBACK
) {
167 event_ctx
->unexpected_event
= 1;
171 if (!mod_hdcp_execute_and_set(mod_hdcp_add_display_topology
,
172 &input
->add_topology
, &status
,
173 hdcp
, "add_topology"))
175 if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp1_create_session
,
176 &input
->create_session
, &status
,
177 hdcp
, "create_session"))
179 if (!mod_hdcp_execute_and_set(mod_hdcp_write_an
,
180 &input
->an_write
, &status
,
183 if (!mod_hdcp_execute_and_set(mod_hdcp_write_aksv
,
184 &input
->aksv_write
, &status
,
187 if (!mod_hdcp_execute_and_set(mod_hdcp_read_bksv
,
188 &input
->bksv_read
, &status
,
191 if (!mod_hdcp_execute_and_set(validate_bksv
,
192 &input
->bksv_validation
, &status
,
193 hdcp
, "bksv_validation"))
195 if (hdcp
->auth
.msg
.hdcp1
.ainfo
) {
196 if (!mod_hdcp_execute_and_set(mod_hdcp_write_ainfo
,
197 &input
->ainfo_write
, &status
,
198 hdcp
, "ainfo_write"))
205 static enum mod_hdcp_status
computations_validate_rx_test_for_repeater(
206 struct mod_hdcp
*hdcp
,
207 struct mod_hdcp_event_context
*event_ctx
,
208 struct mod_hdcp_transition_input_hdcp1
*input
)
210 enum mod_hdcp_status status
= MOD_HDCP_STATUS_SUCCESS
;
212 if (event_ctx
->event
!= MOD_HDCP_EVENT_CALLBACK
) {
213 event_ctx
->unexpected_event
= 1;
217 if (!mod_hdcp_execute_and_set(mod_hdcp_read_r0p
,
218 &input
->r0p_read
, &status
,
221 if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp1_validate_rx
,
222 &input
->rx_validation
, &status
,
223 hdcp
, "rx_validation"))
225 if (hdcp
->connection
.is_repeater
) {
226 if (!hdcp
->connection
.link
.adjust
.hdcp1
.postpone_encryption
)
227 if (!mod_hdcp_execute_and_set(
228 mod_hdcp_hdcp1_enable_encryption
,
229 &input
->encryption
, &status
,
233 if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp1_enable_encryption
,
234 &input
->encryption
, &status
,
237 if (is_dp_mst_hdcp(hdcp
))
238 if (!mod_hdcp_execute_and_set(
239 mod_hdcp_hdcp1_enable_dp_stream_encryption
,
240 &input
->stream_encryption_dp
, &status
,
241 hdcp
, "stream_encryption_dp"))
248 static enum mod_hdcp_status
authenticated(struct mod_hdcp
*hdcp
,
249 struct mod_hdcp_event_context
*event_ctx
,
250 struct mod_hdcp_transition_input_hdcp1
*input
)
252 enum mod_hdcp_status status
= MOD_HDCP_STATUS_SUCCESS
;
254 if (event_ctx
->event
!= MOD_HDCP_EVENT_CALLBACK
) {
255 event_ctx
->unexpected_event
= 1;
259 if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp1_link_maintenance
,
260 &input
->link_maintenance
, &status
,
261 hdcp
, "link_maintenance"))
267 static enum mod_hdcp_status
wait_for_ready(struct mod_hdcp
*hdcp
,
268 struct mod_hdcp_event_context
*event_ctx
,
269 struct mod_hdcp_transition_input_hdcp1
*input
)
271 enum mod_hdcp_status status
= MOD_HDCP_STATUS_SUCCESS
;
273 if (event_ctx
->event
!= MOD_HDCP_EVENT_CALLBACK
&&
274 event_ctx
->event
!= MOD_HDCP_EVENT_CPIRQ
&&
275 event_ctx
->event
!= MOD_HDCP_EVENT_WATCHDOG_TIMEOUT
) {
276 event_ctx
->unexpected_event
= 1;
280 if (is_dp_hdcp(hdcp
)) {
281 if (!mod_hdcp_execute_and_set(mod_hdcp_read_bstatus
,
282 &input
->bstatus_read
, &status
,
283 hdcp
, "bstatus_read"))
285 if (!mod_hdcp_execute_and_set(check_link_integrity_dp
,
286 &input
->link_integiry_check
, &status
,
287 hdcp
, "link_integiry_check"))
289 if (!mod_hdcp_execute_and_set(check_no_reauthentication_request_dp
,
290 &input
->reauth_request_check
, &status
,
291 hdcp
, "reauth_request_check"))
294 if (!mod_hdcp_execute_and_set(mod_hdcp_read_bcaps
,
295 &input
->bcaps_read
, &status
,
299 if (!mod_hdcp_execute_and_set(check_ksv_ready
,
300 &input
->ready_check
, &status
,
301 hdcp
, "ready_check"))
307 static enum mod_hdcp_status
read_ksv_list(struct mod_hdcp
*hdcp
,
308 struct mod_hdcp_event_context
*event_ctx
,
309 struct mod_hdcp_transition_input_hdcp1
*input
)
311 enum mod_hdcp_status status
= MOD_HDCP_STATUS_SUCCESS
;
312 uint8_t device_count
;
314 if (event_ctx
->event
!= MOD_HDCP_EVENT_CALLBACK
) {
315 event_ctx
->unexpected_event
= 1;
319 if (is_dp_hdcp(hdcp
)) {
320 if (!mod_hdcp_execute_and_set(mod_hdcp_read_binfo
,
321 &input
->binfo_read_dp
, &status
,
322 hdcp
, "binfo_read_dp"))
325 if (!mod_hdcp_execute_and_set(mod_hdcp_read_bstatus
,
326 &input
->bstatus_read
, &status
,
327 hdcp
, "bstatus_read"))
330 if (!mod_hdcp_execute_and_set(check_no_max_cascade
,
331 &input
->max_cascade_check
, &status
,
332 hdcp
, "max_cascade_check"))
334 if (!mod_hdcp_execute_and_set(check_no_max_devs
,
335 &input
->max_devs_check
, &status
,
336 hdcp
, "max_devs_check"))
338 if (!mod_hdcp_execute_and_set(check_device_count
,
339 &input
->device_count_check
, &status
,
340 hdcp
, "device_count_check"))
342 device_count
= get_device_count(hdcp
);
343 hdcp
->auth
.msg
.hdcp1
.ksvlist_size
= device_count
*5;
344 if (!mod_hdcp_execute_and_set(mod_hdcp_read_ksvlist
,
345 &input
->ksvlist_read
, &status
,
346 hdcp
, "ksvlist_read"))
348 if (!mod_hdcp_execute_and_set(mod_hdcp_read_vp
,
349 &input
->vp_read
, &status
,
352 if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp1_validate_ksvlist_vp
,
353 &input
->ksvlist_vp_validation
, &status
,
354 hdcp
, "ksvlist_vp_validation"))
356 if (input
->encryption
!= PASS
)
357 if (!mod_hdcp_execute_and_set(mod_hdcp_hdcp1_enable_encryption
,
358 &input
->encryption
, &status
,
361 if (is_dp_mst_hdcp(hdcp
))
362 if (!mod_hdcp_execute_and_set(
363 mod_hdcp_hdcp1_enable_dp_stream_encryption
,
364 &input
->stream_encryption_dp
, &status
,
365 hdcp
, "stream_encryption_dp"))
371 static enum mod_hdcp_status
determine_rx_hdcp_capable_dp(struct mod_hdcp
*hdcp
,
372 struct mod_hdcp_event_context
*event_ctx
,
373 struct mod_hdcp_transition_input_hdcp1
*input
)
375 enum mod_hdcp_status status
= MOD_HDCP_STATUS_SUCCESS
;
377 if (event_ctx
->event
!= MOD_HDCP_EVENT_CALLBACK
) {
378 event_ctx
->unexpected_event
= 1;
382 if (!mod_hdcp_execute_and_set(mod_hdcp_read_bcaps
,
383 &input
->bcaps_read
, &status
,
386 if (!mod_hdcp_execute_and_set(check_hdcp_capable_dp
,
387 &input
->hdcp_capable_dp
, &status
,
388 hdcp
, "hdcp_capable_dp"))
394 static enum mod_hdcp_status
wait_for_r0_prime_dp(struct mod_hdcp
*hdcp
,
395 struct mod_hdcp_event_context
*event_ctx
,
396 struct mod_hdcp_transition_input_hdcp1
*input
)
398 enum mod_hdcp_status status
= MOD_HDCP_STATUS_SUCCESS
;
400 if (event_ctx
->event
!= MOD_HDCP_EVENT_CPIRQ
&&
401 event_ctx
->event
!= MOD_HDCP_EVENT_WATCHDOG_TIMEOUT
) {
402 event_ctx
->unexpected_event
= 1;
406 if (!mod_hdcp_execute_and_set(mod_hdcp_read_bstatus
,
407 &input
->bstatus_read
, &status
,
408 hdcp
, "bstatus_read"))
410 if (!mod_hdcp_execute_and_set(check_r0p_available_dp
,
411 &input
->r0p_available_dp
, &status
,
412 hdcp
, "r0p_available_dp"))
418 static enum mod_hdcp_status
authenticated_dp(struct mod_hdcp
*hdcp
,
419 struct mod_hdcp_event_context
*event_ctx
,
420 struct mod_hdcp_transition_input_hdcp1
*input
)
422 enum mod_hdcp_status status
= MOD_HDCP_STATUS_SUCCESS
;
424 if (event_ctx
->event
!= MOD_HDCP_EVENT_CPIRQ
) {
425 event_ctx
->unexpected_event
= 1;
429 if (!mod_hdcp_execute_and_set(mod_hdcp_read_bstatus
,
430 &input
->bstatus_read
, &status
,
431 hdcp
, "bstatus_read"))
433 if (!mod_hdcp_execute_and_set(check_link_integrity_dp
,
434 &input
->link_integiry_check
, &status
,
435 hdcp
, "link_integiry_check"))
437 if (!mod_hdcp_execute_and_set(check_no_reauthentication_request_dp
,
438 &input
->reauth_request_check
, &status
,
439 hdcp
, "reauth_request_check"))
445 uint8_t mod_hdcp_execute_and_set(
446 mod_hdcp_action func
, uint8_t *flag
,
447 enum mod_hdcp_status
*status
, struct mod_hdcp
*hdcp
, char *str
)
449 *status
= func(hdcp
);
450 if (*status
== MOD_HDCP_STATUS_SUCCESS
&& *flag
!= PASS
) {
451 HDCP_INPUT_PASS_TRACE(hdcp
, str
);
453 } else if (*status
!= MOD_HDCP_STATUS_SUCCESS
&& *flag
!= FAIL
) {
454 HDCP_INPUT_FAIL_TRACE(hdcp
, str
);
457 return (*status
== MOD_HDCP_STATUS_SUCCESS
);
460 enum mod_hdcp_status
mod_hdcp_hdcp1_execution(struct mod_hdcp
*hdcp
,
461 struct mod_hdcp_event_context
*event_ctx
,
462 struct mod_hdcp_transition_input_hdcp1
*input
)
464 enum mod_hdcp_status status
= MOD_HDCP_STATUS_SUCCESS
;
466 switch (current_state(hdcp
)) {
467 case H1_A0_WAIT_FOR_ACTIVE_RX
:
468 status
= wait_for_active_rx(hdcp
, event_ctx
, input
);
470 case H1_A1_EXCHANGE_KSVS
:
471 status
= exchange_ksvs(hdcp
, event_ctx
, input
);
473 case H1_A2_COMPUTATIONS_A3_VALIDATE_RX_A6_TEST_FOR_REPEATER
:
474 status
= computations_validate_rx_test_for_repeater(hdcp
,
477 case H1_A45_AUTHENTICATED
:
478 status
= authenticated(hdcp
, event_ctx
, input
);
480 case H1_A8_WAIT_FOR_READY
:
481 status
= wait_for_ready(hdcp
, event_ctx
, input
);
483 case H1_A9_READ_KSV_LIST
:
484 status
= read_ksv_list(hdcp
, event_ctx
, input
);
487 status
= MOD_HDCP_STATUS_INVALID_STATE
;
494 extern enum mod_hdcp_status
mod_hdcp_hdcp1_dp_execution(struct mod_hdcp
*hdcp
,
495 struct mod_hdcp_event_context
*event_ctx
,
496 struct mod_hdcp_transition_input_hdcp1
*input
)
498 enum mod_hdcp_status status
= MOD_HDCP_STATUS_SUCCESS
;
500 switch (current_state(hdcp
)) {
501 case D1_A0_DETERMINE_RX_HDCP_CAPABLE
:
502 status
= determine_rx_hdcp_capable_dp(hdcp
, event_ctx
, input
);
504 case D1_A1_EXCHANGE_KSVS
:
505 status
= exchange_ksvs(hdcp
, event_ctx
, input
);
507 case D1_A23_WAIT_FOR_R0_PRIME
:
508 status
= wait_for_r0_prime_dp(hdcp
, event_ctx
, input
);
510 case D1_A2_COMPUTATIONS_A3_VALIDATE_RX_A5_TEST_FOR_REPEATER
:
511 status
= computations_validate_rx_test_for_repeater(
512 hdcp
, event_ctx
, input
);
514 case D1_A4_AUTHENTICATED
:
515 status
= authenticated_dp(hdcp
, event_ctx
, input
);
517 case D1_A6_WAIT_FOR_READY
:
518 status
= wait_for_ready(hdcp
, event_ctx
, input
);
520 case D1_A7_READ_KSV_LIST
:
521 status
= read_ksv_list(hdcp
, event_ctx
, input
);
524 status
= MOD_HDCP_STATUS_INVALID_STATE
;