1c349dbc7Sjsg /*
2c349dbc7Sjsg * Copyright 2019 Advanced Micro Devices, Inc.
3c349dbc7Sjsg *
4c349dbc7Sjsg * Permission is hereby granted, free of charge, to any person obtaining a
5c349dbc7Sjsg * copy of this software and associated documentation files (the "Software"),
6c349dbc7Sjsg * to deal in the Software without restriction, including without limitation
7c349dbc7Sjsg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8c349dbc7Sjsg * and/or sell copies of the Software, and to permit persons to whom the
9c349dbc7Sjsg * Software is furnished to do so, subject to the following conditions:
10c349dbc7Sjsg *
11c349dbc7Sjsg * The above copyright notice and this permission notice shall be included in
12c349dbc7Sjsg * all copies or substantial portions of the Software.
13c349dbc7Sjsg *
14c349dbc7Sjsg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15c349dbc7Sjsg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16c349dbc7Sjsg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17c349dbc7Sjsg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18c349dbc7Sjsg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19c349dbc7Sjsg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20c349dbc7Sjsg * OTHER DEALINGS IN THE SOFTWARE.
21c349dbc7Sjsg *
22c349dbc7Sjsg * Authors: AMD
23c349dbc7Sjsg *
24c349dbc7Sjsg */
25c349dbc7Sjsg
26c349dbc7Sjsg #ifndef HDCP_H_
27c349dbc7Sjsg #define HDCP_H_
28c349dbc7Sjsg
29c349dbc7Sjsg #include "mod_hdcp.h"
30c349dbc7Sjsg #include "hdcp_log.h"
31c349dbc7Sjsg
32*1bb76ff1Sjsg #include <drm/display/drm_dp_helper.h>
33*1bb76ff1Sjsg #include <drm/display/drm_hdcp_helper.h>
34c349dbc7Sjsg
35c349dbc7Sjsg enum mod_hdcp_trans_input_result {
36c349dbc7Sjsg UNKNOWN = 0,
37c349dbc7Sjsg PASS,
38c349dbc7Sjsg FAIL
39c349dbc7Sjsg };
40c349dbc7Sjsg
41c349dbc7Sjsg struct mod_hdcp_transition_input_hdcp1 {
42c349dbc7Sjsg uint8_t bksv_read;
43c349dbc7Sjsg uint8_t bksv_validation;
44c349dbc7Sjsg uint8_t create_session;
45c349dbc7Sjsg uint8_t an_write;
46c349dbc7Sjsg uint8_t aksv_write;
47c349dbc7Sjsg uint8_t ainfo_write;
48c349dbc7Sjsg uint8_t bcaps_read;
49c349dbc7Sjsg uint8_t r0p_read;
50c349dbc7Sjsg uint8_t rx_validation;
51c349dbc7Sjsg uint8_t encryption;
52c349dbc7Sjsg uint8_t link_maintenance;
53c349dbc7Sjsg uint8_t ready_check;
54c349dbc7Sjsg uint8_t bstatus_read;
55c349dbc7Sjsg uint8_t max_cascade_check;
56c349dbc7Sjsg uint8_t max_devs_check;
57c349dbc7Sjsg uint8_t device_count_check;
58c349dbc7Sjsg uint8_t ksvlist_read;
59c349dbc7Sjsg uint8_t vp_read;
60c349dbc7Sjsg uint8_t ksvlist_vp_validation;
61c349dbc7Sjsg
62c349dbc7Sjsg uint8_t hdcp_capable_dp;
63c349dbc7Sjsg uint8_t binfo_read_dp;
64c349dbc7Sjsg uint8_t r0p_available_dp;
65c349dbc7Sjsg uint8_t link_integrity_check;
66c349dbc7Sjsg uint8_t reauth_request_check;
67c349dbc7Sjsg uint8_t stream_encryption_dp;
68c349dbc7Sjsg };
69c349dbc7Sjsg
70c349dbc7Sjsg struct mod_hdcp_transition_input_hdcp2 {
71c349dbc7Sjsg uint8_t hdcp2version_read;
72c349dbc7Sjsg uint8_t hdcp2_capable_check;
73c349dbc7Sjsg uint8_t create_session;
74c349dbc7Sjsg uint8_t ake_init_prepare;
75c349dbc7Sjsg uint8_t ake_init_write;
76c349dbc7Sjsg uint8_t rxstatus_read;
77c349dbc7Sjsg uint8_t ake_cert_available;
78c349dbc7Sjsg uint8_t ake_cert_read;
79c349dbc7Sjsg uint8_t ake_cert_validation;
80c349dbc7Sjsg uint8_t stored_km_write;
81c349dbc7Sjsg uint8_t no_stored_km_write;
82c349dbc7Sjsg uint8_t h_prime_available;
83c349dbc7Sjsg uint8_t h_prime_read;
84c349dbc7Sjsg uint8_t pairing_available;
85c349dbc7Sjsg uint8_t pairing_info_read;
86c349dbc7Sjsg uint8_t h_prime_validation;
87c349dbc7Sjsg uint8_t lc_init_prepare;
88c349dbc7Sjsg uint8_t lc_init_write;
89c349dbc7Sjsg uint8_t l_prime_available_poll;
90c349dbc7Sjsg uint8_t l_prime_read;
91c349dbc7Sjsg uint8_t l_prime_validation;
92c349dbc7Sjsg uint8_t eks_prepare;
93c349dbc7Sjsg uint8_t eks_write;
94c349dbc7Sjsg uint8_t enable_encryption;
95c349dbc7Sjsg uint8_t reauth_request_check;
96c349dbc7Sjsg uint8_t rx_id_list_read;
97c349dbc7Sjsg uint8_t device_count_check;
98c349dbc7Sjsg uint8_t rx_id_list_validation;
99c349dbc7Sjsg uint8_t repeater_auth_ack_write;
100c349dbc7Sjsg uint8_t prepare_stream_manage;
101c349dbc7Sjsg uint8_t stream_manage_write;
102c349dbc7Sjsg uint8_t stream_ready_available;
103c349dbc7Sjsg uint8_t stream_ready_read;
104c349dbc7Sjsg uint8_t stream_ready_validation;
105c349dbc7Sjsg
106c349dbc7Sjsg uint8_t rx_caps_read_dp;
107c349dbc7Sjsg uint8_t content_stream_type_write;
108c349dbc7Sjsg uint8_t link_integrity_check_dp;
109c349dbc7Sjsg uint8_t stream_encryption_dp;
110c349dbc7Sjsg };
111c349dbc7Sjsg
112c349dbc7Sjsg union mod_hdcp_transition_input {
113c349dbc7Sjsg struct mod_hdcp_transition_input_hdcp1 hdcp1;
114c349dbc7Sjsg struct mod_hdcp_transition_input_hdcp2 hdcp2;
115c349dbc7Sjsg };
116c349dbc7Sjsg
117c349dbc7Sjsg struct mod_hdcp_message_hdcp1 {
118c349dbc7Sjsg uint8_t an[8];
119c349dbc7Sjsg uint8_t aksv[5];
120c349dbc7Sjsg uint8_t ainfo;
121c349dbc7Sjsg uint8_t bksv[5];
122c349dbc7Sjsg uint16_t r0p;
123c349dbc7Sjsg uint8_t bcaps;
124c349dbc7Sjsg uint16_t bstatus;
125c349dbc7Sjsg uint8_t ksvlist[635];
126c349dbc7Sjsg uint16_t ksvlist_size;
127c349dbc7Sjsg uint8_t vp[20];
128c349dbc7Sjsg
129c349dbc7Sjsg uint16_t binfo_dp;
130c349dbc7Sjsg };
131c349dbc7Sjsg
132c349dbc7Sjsg struct mod_hdcp_message_hdcp2 {
133c349dbc7Sjsg uint8_t hdcp2version_hdmi;
134c349dbc7Sjsg uint8_t rxcaps_dp[3];
135c349dbc7Sjsg uint8_t rxstatus[2];
136c349dbc7Sjsg
137c349dbc7Sjsg uint8_t ake_init[12];
138c349dbc7Sjsg uint8_t ake_cert[534];
139c349dbc7Sjsg uint8_t ake_no_stored_km[129];
140c349dbc7Sjsg uint8_t ake_stored_km[33];
141c349dbc7Sjsg uint8_t ake_h_prime[33];
142c349dbc7Sjsg uint8_t ake_pairing_info[17];
143c349dbc7Sjsg uint8_t lc_init[9];
144c349dbc7Sjsg uint8_t lc_l_prime[33];
145c349dbc7Sjsg uint8_t ske_eks[25];
146c349dbc7Sjsg uint8_t rx_id_list[177]; // 22 + 5 * 31
147c349dbc7Sjsg uint16_t rx_id_list_size;
148c349dbc7Sjsg uint8_t repeater_auth_ack[17];
149c349dbc7Sjsg uint8_t repeater_auth_stream_manage[68]; // 6 + 2 * 31
150c349dbc7Sjsg uint16_t stream_manage_size;
151c349dbc7Sjsg uint8_t repeater_auth_stream_ready[33];
152c349dbc7Sjsg uint8_t rxstatus_dp;
153c349dbc7Sjsg uint8_t content_stream_type_dp[2];
154c349dbc7Sjsg };
155c349dbc7Sjsg
156c349dbc7Sjsg union mod_hdcp_message {
157c349dbc7Sjsg struct mod_hdcp_message_hdcp1 hdcp1;
158c349dbc7Sjsg struct mod_hdcp_message_hdcp2 hdcp2;
159c349dbc7Sjsg };
160c349dbc7Sjsg
161c349dbc7Sjsg struct mod_hdcp_auth_counters {
162c349dbc7Sjsg uint8_t stream_management_retry_count;
163c349dbc7Sjsg };
164c349dbc7Sjsg
165c349dbc7Sjsg /* contains values per connection */
166c349dbc7Sjsg struct mod_hdcp_connection {
167c349dbc7Sjsg struct mod_hdcp_link link;
168c349dbc7Sjsg uint8_t is_repeater;
169c349dbc7Sjsg uint8_t is_km_stored;
170c349dbc7Sjsg uint8_t is_hdcp1_revoked;
171c349dbc7Sjsg uint8_t is_hdcp2_revoked;
172c349dbc7Sjsg struct mod_hdcp_trace trace;
173c349dbc7Sjsg uint8_t hdcp1_retry_count;
174c349dbc7Sjsg uint8_t hdcp2_retry_count;
175c349dbc7Sjsg };
176c349dbc7Sjsg
177c349dbc7Sjsg /* contains values per authentication cycle */
178c349dbc7Sjsg struct mod_hdcp_authentication {
179c349dbc7Sjsg uint32_t id;
180c349dbc7Sjsg union mod_hdcp_message msg;
181c349dbc7Sjsg union mod_hdcp_transition_input trans_input;
182c349dbc7Sjsg struct mod_hdcp_auth_counters count;
183c349dbc7Sjsg };
184c349dbc7Sjsg
185c349dbc7Sjsg /* contains values per state change */
186c349dbc7Sjsg struct mod_hdcp_state {
187c349dbc7Sjsg uint8_t id;
188c349dbc7Sjsg uint32_t stay_count;
189c349dbc7Sjsg };
190c349dbc7Sjsg
191c349dbc7Sjsg /* per event in a state */
192c349dbc7Sjsg struct mod_hdcp_event_context {
193c349dbc7Sjsg enum mod_hdcp_event event;
194c349dbc7Sjsg uint8_t rx_id_list_ready;
195c349dbc7Sjsg uint8_t unexpected_event;
196c349dbc7Sjsg };
197c349dbc7Sjsg
198c349dbc7Sjsg struct mod_hdcp {
199c349dbc7Sjsg /* per link */
200c349dbc7Sjsg struct mod_hdcp_config config;
201c349dbc7Sjsg /* per connection */
202c349dbc7Sjsg struct mod_hdcp_connection connection;
203c349dbc7Sjsg /* per displays */
204c349dbc7Sjsg struct mod_hdcp_display displays[MAX_NUM_OF_DISPLAYS];
205c349dbc7Sjsg /* per authentication attempt */
206c349dbc7Sjsg struct mod_hdcp_authentication auth;
207c349dbc7Sjsg /* per state in an authentication */
208c349dbc7Sjsg struct mod_hdcp_state state;
209c349dbc7Sjsg /* reserved memory buffer */
210c349dbc7Sjsg uint8_t buf[2025];
211c349dbc7Sjsg };
212c349dbc7Sjsg
213c349dbc7Sjsg enum mod_hdcp_initial_state_id {
214c349dbc7Sjsg HDCP_UNINITIALIZED = 0x0,
215c349dbc7Sjsg HDCP_INITIAL_STATE_START = HDCP_UNINITIALIZED,
216c349dbc7Sjsg HDCP_INITIALIZED,
217c349dbc7Sjsg HDCP_CP_NOT_DESIRED,
218c349dbc7Sjsg HDCP_INITIAL_STATE_END = HDCP_CP_NOT_DESIRED
219c349dbc7Sjsg };
220c349dbc7Sjsg
221c349dbc7Sjsg enum mod_hdcp_hdcp1_state_id {
222c349dbc7Sjsg HDCP1_STATE_START = HDCP_INITIAL_STATE_END,
223c349dbc7Sjsg H1_A0_WAIT_FOR_ACTIVE_RX,
224c349dbc7Sjsg H1_A1_EXCHANGE_KSVS,
225c349dbc7Sjsg H1_A2_COMPUTATIONS_A3_VALIDATE_RX_A6_TEST_FOR_REPEATER,
226c349dbc7Sjsg H1_A45_AUTHENTICATED,
227c349dbc7Sjsg H1_A8_WAIT_FOR_READY,
228c349dbc7Sjsg H1_A9_READ_KSV_LIST,
229c349dbc7Sjsg HDCP1_STATE_END = H1_A9_READ_KSV_LIST
230c349dbc7Sjsg };
231c349dbc7Sjsg
232c349dbc7Sjsg enum mod_hdcp_hdcp1_dp_state_id {
233c349dbc7Sjsg HDCP1_DP_STATE_START = HDCP1_STATE_END,
234c349dbc7Sjsg D1_A0_DETERMINE_RX_HDCP_CAPABLE,
235c349dbc7Sjsg D1_A1_EXCHANGE_KSVS,
236c349dbc7Sjsg D1_A23_WAIT_FOR_R0_PRIME,
237c349dbc7Sjsg D1_A2_COMPUTATIONS_A3_VALIDATE_RX_A5_TEST_FOR_REPEATER,
238c349dbc7Sjsg D1_A4_AUTHENTICATED,
239c349dbc7Sjsg D1_A6_WAIT_FOR_READY,
240c349dbc7Sjsg D1_A7_READ_KSV_LIST,
241c349dbc7Sjsg HDCP1_DP_STATE_END = D1_A7_READ_KSV_LIST,
242c349dbc7Sjsg };
243c349dbc7Sjsg
244c349dbc7Sjsg enum mod_hdcp_hdcp2_state_id {
245c349dbc7Sjsg HDCP2_STATE_START = HDCP1_DP_STATE_END,
246c349dbc7Sjsg H2_A0_KNOWN_HDCP2_CAPABLE_RX,
247c349dbc7Sjsg H2_A1_SEND_AKE_INIT,
248c349dbc7Sjsg H2_A1_VALIDATE_AKE_CERT,
249c349dbc7Sjsg H2_A1_SEND_NO_STORED_KM,
250c349dbc7Sjsg H2_A1_READ_H_PRIME,
251c349dbc7Sjsg H2_A1_READ_PAIRING_INFO_AND_VALIDATE_H_PRIME,
252c349dbc7Sjsg H2_A1_SEND_STORED_KM,
253c349dbc7Sjsg H2_A1_VALIDATE_H_PRIME,
254c349dbc7Sjsg H2_A2_LOCALITY_CHECK,
255c349dbc7Sjsg H2_A3_EXCHANGE_KS_AND_TEST_FOR_REPEATER,
256c349dbc7Sjsg H2_ENABLE_ENCRYPTION,
257c349dbc7Sjsg H2_A5_AUTHENTICATED,
258c349dbc7Sjsg H2_A6_WAIT_FOR_RX_ID_LIST,
259c349dbc7Sjsg H2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK,
260c349dbc7Sjsg H2_A9_SEND_STREAM_MANAGEMENT,
261c349dbc7Sjsg H2_A9_VALIDATE_STREAM_READY,
262c349dbc7Sjsg HDCP2_STATE_END = H2_A9_VALIDATE_STREAM_READY,
263c349dbc7Sjsg };
264c349dbc7Sjsg
265c349dbc7Sjsg enum mod_hdcp_hdcp2_dp_state_id {
266c349dbc7Sjsg HDCP2_DP_STATE_START = HDCP2_STATE_END,
267c349dbc7Sjsg D2_A0_DETERMINE_RX_HDCP_CAPABLE,
268c349dbc7Sjsg D2_A1_SEND_AKE_INIT,
269c349dbc7Sjsg D2_A1_VALIDATE_AKE_CERT,
270c349dbc7Sjsg D2_A1_SEND_NO_STORED_KM,
271c349dbc7Sjsg D2_A1_READ_H_PRIME,
272c349dbc7Sjsg D2_A1_READ_PAIRING_INFO_AND_VALIDATE_H_PRIME,
273c349dbc7Sjsg D2_A1_SEND_STORED_KM,
274c349dbc7Sjsg D2_A1_VALIDATE_H_PRIME,
275c349dbc7Sjsg D2_A2_LOCALITY_CHECK,
276c349dbc7Sjsg D2_A34_EXCHANGE_KS_AND_TEST_FOR_REPEATER,
277c349dbc7Sjsg D2_SEND_CONTENT_STREAM_TYPE,
278c349dbc7Sjsg D2_ENABLE_ENCRYPTION,
279c349dbc7Sjsg D2_A5_AUTHENTICATED,
280c349dbc7Sjsg D2_A6_WAIT_FOR_RX_ID_LIST,
281c349dbc7Sjsg D2_A78_VERIFY_RX_ID_LIST_AND_SEND_ACK,
282c349dbc7Sjsg D2_A9_SEND_STREAM_MANAGEMENT,
283c349dbc7Sjsg D2_A9_VALIDATE_STREAM_READY,
284c349dbc7Sjsg HDCP2_DP_STATE_END = D2_A9_VALIDATE_STREAM_READY,
285c349dbc7Sjsg HDCP_STATE_END = HDCP2_DP_STATE_END,
286c349dbc7Sjsg };
287c349dbc7Sjsg
288c349dbc7Sjsg /* hdcp1 executions and transitions */
289c349dbc7Sjsg typedef enum mod_hdcp_status (*mod_hdcp_action)(struct mod_hdcp *hdcp);
290c349dbc7Sjsg uint8_t mod_hdcp_execute_and_set(
291c349dbc7Sjsg mod_hdcp_action func, uint8_t *flag,
292c349dbc7Sjsg enum mod_hdcp_status *status, struct mod_hdcp *hdcp, char *str);
293c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp1_execution(struct mod_hdcp *hdcp,
294c349dbc7Sjsg struct mod_hdcp_event_context *event_ctx,
295c349dbc7Sjsg struct mod_hdcp_transition_input_hdcp1 *input);
296c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp1_dp_execution(struct mod_hdcp *hdcp,
297c349dbc7Sjsg struct mod_hdcp_event_context *event_ctx,
298c349dbc7Sjsg struct mod_hdcp_transition_input_hdcp1 *input);
299c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp1_transition(struct mod_hdcp *hdcp,
300c349dbc7Sjsg struct mod_hdcp_event_context *event_ctx,
301c349dbc7Sjsg struct mod_hdcp_transition_input_hdcp1 *input,
302c349dbc7Sjsg struct mod_hdcp_output *output);
303c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp1_dp_transition(struct mod_hdcp *hdcp,
304c349dbc7Sjsg struct mod_hdcp_event_context *event_ctx,
305c349dbc7Sjsg struct mod_hdcp_transition_input_hdcp1 *input,
306c349dbc7Sjsg struct mod_hdcp_output *output);
307c349dbc7Sjsg
308c349dbc7Sjsg /* hdcp2 executions and transitions */
309c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp2_execution(struct mod_hdcp *hdcp,
310c349dbc7Sjsg struct mod_hdcp_event_context *event_ctx,
311c349dbc7Sjsg struct mod_hdcp_transition_input_hdcp2 *input);
312c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp2_dp_execution(struct mod_hdcp *hdcp,
313c349dbc7Sjsg struct mod_hdcp_event_context *event_ctx,
314c349dbc7Sjsg struct mod_hdcp_transition_input_hdcp2 *input);
315c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp2_transition(struct mod_hdcp *hdcp,
316c349dbc7Sjsg struct mod_hdcp_event_context *event_ctx,
317c349dbc7Sjsg struct mod_hdcp_transition_input_hdcp2 *input,
318c349dbc7Sjsg struct mod_hdcp_output *output);
319c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp2_dp_transition(struct mod_hdcp *hdcp,
320c349dbc7Sjsg struct mod_hdcp_event_context *event_ctx,
321c349dbc7Sjsg struct mod_hdcp_transition_input_hdcp2 *input,
322c349dbc7Sjsg struct mod_hdcp_output *output);
323c349dbc7Sjsg
324c349dbc7Sjsg /* log functions */
325c349dbc7Sjsg void mod_hdcp_dump_binary_message(uint8_t *msg, uint32_t msg_size,
326c349dbc7Sjsg uint8_t *buf, uint32_t buf_size);
3275ca02815Sjsg void mod_hdcp_log_ddc_trace(struct mod_hdcp *hdcp);
328c349dbc7Sjsg /* TODO: add adjustment log */
329c349dbc7Sjsg
330c349dbc7Sjsg /* psp functions */
331c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_add_display_to_topology(
332ad8b1aafSjsg struct mod_hdcp *hdcp, struct mod_hdcp_display *display);
333c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_remove_display_from_topology(
334c349dbc7Sjsg struct mod_hdcp *hdcp, uint8_t index);
335c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp1_create_session(struct mod_hdcp *hdcp);
336c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp1_destroy_session(struct mod_hdcp *hdcp);
337c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp1_validate_rx(struct mod_hdcp *hdcp);
338c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp1_enable_encryption(struct mod_hdcp *hdcp);
339c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp1_validate_ksvlist_vp(struct mod_hdcp *hdcp);
340c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp1_enable_dp_stream_encryption(
341c349dbc7Sjsg struct mod_hdcp *hdcp);
342c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp1_link_maintenance(struct mod_hdcp *hdcp);
343c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp2_create_session(struct mod_hdcp *hdcp);
344c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp2_destroy_session(struct mod_hdcp *hdcp);
345c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp2_prepare_ake_init(struct mod_hdcp *hdcp);
346c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp2_validate_ake_cert(struct mod_hdcp *hdcp);
347c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp2_validate_h_prime(struct mod_hdcp *hdcp);
348c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp2_prepare_lc_init(struct mod_hdcp *hdcp);
349c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp2_validate_l_prime(struct mod_hdcp *hdcp);
350c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp2_prepare_eks(struct mod_hdcp *hdcp);
351c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp2_enable_encryption(struct mod_hdcp *hdcp);
352c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp2_validate_rx_id_list(struct mod_hdcp *hdcp);
353c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp2_enable_dp_stream_encryption(
354c349dbc7Sjsg struct mod_hdcp *hdcp);
355c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp2_prepare_stream_management(
356c349dbc7Sjsg struct mod_hdcp *hdcp);
357c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_hdcp2_validate_stream_ready(
358c349dbc7Sjsg struct mod_hdcp *hdcp);
359c349dbc7Sjsg
360c349dbc7Sjsg /* ddc functions */
361c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_bksv(struct mod_hdcp *hdcp);
362c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_bcaps(struct mod_hdcp *hdcp);
363c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_bstatus(struct mod_hdcp *hdcp);
364c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_r0p(struct mod_hdcp *hdcp);
365c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_ksvlist(struct mod_hdcp *hdcp);
366c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_vp(struct mod_hdcp *hdcp);
367c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_binfo(struct mod_hdcp *hdcp);
368c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_write_aksv(struct mod_hdcp *hdcp);
369c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_write_ainfo(struct mod_hdcp *hdcp);
370c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_write_an(struct mod_hdcp *hdcp);
371c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_hdcp2version(struct mod_hdcp *hdcp);
372c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_rxcaps(struct mod_hdcp *hdcp);
373c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_rxstatus(struct mod_hdcp *hdcp);
374c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_ake_cert(struct mod_hdcp *hdcp);
375c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_h_prime(struct mod_hdcp *hdcp);
376c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_pairing_info(struct mod_hdcp *hdcp);
377c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_l_prime(struct mod_hdcp *hdcp);
378c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_rx_id_list(struct mod_hdcp *hdcp);
379c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_stream_ready(struct mod_hdcp *hdcp);
380c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_write_ake_init(struct mod_hdcp *hdcp);
381c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_write_no_stored_km(struct mod_hdcp *hdcp);
382c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_write_stored_km(struct mod_hdcp *hdcp);
383c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_write_lc_init(struct mod_hdcp *hdcp);
384c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_write_eks(struct mod_hdcp *hdcp);
385c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_write_repeater_auth_ack(struct mod_hdcp *hdcp);
386c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_write_stream_manage(struct mod_hdcp *hdcp);
387c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_write_content_type(struct mod_hdcp *hdcp);
388ad8b1aafSjsg enum mod_hdcp_status mod_hdcp_clear_cp_irq_status(struct mod_hdcp *hdcp);
389c349dbc7Sjsg
390c349dbc7Sjsg /* hdcp version helpers */
is_dp_hdcp(struct mod_hdcp * hdcp)391c349dbc7Sjsg static inline uint8_t is_dp_hdcp(struct mod_hdcp *hdcp)
392c349dbc7Sjsg {
393c349dbc7Sjsg return (hdcp->connection.link.mode == MOD_HDCP_MODE_DP);
394c349dbc7Sjsg }
395c349dbc7Sjsg
is_dp_mst_hdcp(struct mod_hdcp * hdcp)396c349dbc7Sjsg static inline uint8_t is_dp_mst_hdcp(struct mod_hdcp *hdcp)
397c349dbc7Sjsg {
398c349dbc7Sjsg return (hdcp->connection.link.mode == MOD_HDCP_MODE_DP &&
3995ca02815Sjsg hdcp->connection.link.dp.mst_enabled);
400c349dbc7Sjsg }
401c349dbc7Sjsg
is_hdmi_dvi_sl_hdcp(struct mod_hdcp * hdcp)402c349dbc7Sjsg static inline uint8_t is_hdmi_dvi_sl_hdcp(struct mod_hdcp *hdcp)
403c349dbc7Sjsg {
404c349dbc7Sjsg return (hdcp->connection.link.mode == MOD_HDCP_MODE_DEFAULT);
405c349dbc7Sjsg }
406c349dbc7Sjsg
407c349dbc7Sjsg /* hdcp state helpers */
current_state(struct mod_hdcp * hdcp)408c349dbc7Sjsg static inline uint8_t current_state(struct mod_hdcp *hdcp)
409c349dbc7Sjsg {
410c349dbc7Sjsg return hdcp->state.id;
411c349dbc7Sjsg }
412c349dbc7Sjsg
set_state_id(struct mod_hdcp * hdcp,struct mod_hdcp_output * output,uint8_t id)413c349dbc7Sjsg static inline void set_state_id(struct mod_hdcp *hdcp,
414c349dbc7Sjsg struct mod_hdcp_output *output, uint8_t id)
415c349dbc7Sjsg {
416c349dbc7Sjsg memset(&hdcp->state, 0, sizeof(hdcp->state));
417c349dbc7Sjsg hdcp->state.id = id;
418c349dbc7Sjsg /* callback timer should be reset per state */
419c349dbc7Sjsg output->callback_stop = 1;
420c349dbc7Sjsg output->watchdog_timer_stop = 1;
421c349dbc7Sjsg HDCP_NEXT_STATE_TRACE(hdcp, id, output);
422c349dbc7Sjsg }
423c349dbc7Sjsg
is_in_hdcp1_states(struct mod_hdcp * hdcp)424c349dbc7Sjsg static inline uint8_t is_in_hdcp1_states(struct mod_hdcp *hdcp)
425c349dbc7Sjsg {
426c349dbc7Sjsg return (current_state(hdcp) > HDCP1_STATE_START &&
427c349dbc7Sjsg current_state(hdcp) <= HDCP1_STATE_END);
428c349dbc7Sjsg }
429c349dbc7Sjsg
is_in_hdcp1_dp_states(struct mod_hdcp * hdcp)430c349dbc7Sjsg static inline uint8_t is_in_hdcp1_dp_states(struct mod_hdcp *hdcp)
431c349dbc7Sjsg {
432c349dbc7Sjsg return (current_state(hdcp) > HDCP1_DP_STATE_START &&
433c349dbc7Sjsg current_state(hdcp) <= HDCP1_DP_STATE_END);
434c349dbc7Sjsg }
435c349dbc7Sjsg
is_in_hdcp2_states(struct mod_hdcp * hdcp)436c349dbc7Sjsg static inline uint8_t is_in_hdcp2_states(struct mod_hdcp *hdcp)
437c349dbc7Sjsg {
438c349dbc7Sjsg return (current_state(hdcp) > HDCP2_STATE_START &&
439c349dbc7Sjsg current_state(hdcp) <= HDCP2_STATE_END);
440c349dbc7Sjsg }
441c349dbc7Sjsg
is_in_hdcp2_dp_states(struct mod_hdcp * hdcp)442c349dbc7Sjsg static inline uint8_t is_in_hdcp2_dp_states(struct mod_hdcp *hdcp)
443c349dbc7Sjsg {
444c349dbc7Sjsg return (current_state(hdcp) > HDCP2_DP_STATE_START &&
445c349dbc7Sjsg current_state(hdcp) <= HDCP2_DP_STATE_END);
446c349dbc7Sjsg }
447c349dbc7Sjsg
is_in_authenticated_states(struct mod_hdcp * hdcp)448*1bb76ff1Sjsg static inline uint8_t is_in_authenticated_states(struct mod_hdcp *hdcp)
449*1bb76ff1Sjsg {
450*1bb76ff1Sjsg return (current_state(hdcp) == D1_A4_AUTHENTICATED ||
451*1bb76ff1Sjsg current_state(hdcp) == H1_A45_AUTHENTICATED ||
452*1bb76ff1Sjsg current_state(hdcp) == D2_A5_AUTHENTICATED ||
453*1bb76ff1Sjsg current_state(hdcp) == H2_A5_AUTHENTICATED);
454*1bb76ff1Sjsg }
455*1bb76ff1Sjsg
is_hdcp1(struct mod_hdcp * hdcp)456c349dbc7Sjsg static inline uint8_t is_hdcp1(struct mod_hdcp *hdcp)
457c349dbc7Sjsg {
458c349dbc7Sjsg return (is_in_hdcp1_states(hdcp) || is_in_hdcp1_dp_states(hdcp));
459c349dbc7Sjsg }
460c349dbc7Sjsg
is_hdcp2(struct mod_hdcp * hdcp)461c349dbc7Sjsg static inline uint8_t is_hdcp2(struct mod_hdcp *hdcp)
462c349dbc7Sjsg {
463c349dbc7Sjsg return (is_in_hdcp2_states(hdcp) || is_in_hdcp2_dp_states(hdcp));
464c349dbc7Sjsg }
465c349dbc7Sjsg
is_in_cp_not_desired_state(struct mod_hdcp * hdcp)466c349dbc7Sjsg static inline uint8_t is_in_cp_not_desired_state(struct mod_hdcp *hdcp)
467c349dbc7Sjsg {
468c349dbc7Sjsg return current_state(hdcp) == HDCP_CP_NOT_DESIRED;
469c349dbc7Sjsg }
470c349dbc7Sjsg
is_in_initialized_state(struct mod_hdcp * hdcp)471c349dbc7Sjsg static inline uint8_t is_in_initialized_state(struct mod_hdcp *hdcp)
472c349dbc7Sjsg {
473c349dbc7Sjsg return current_state(hdcp) == HDCP_INITIALIZED;
474c349dbc7Sjsg }
475c349dbc7Sjsg
476c349dbc7Sjsg /* transition operation helpers */
increment_stay_counter(struct mod_hdcp * hdcp)477c349dbc7Sjsg static inline void increment_stay_counter(struct mod_hdcp *hdcp)
478c349dbc7Sjsg {
479c349dbc7Sjsg hdcp->state.stay_count++;
480c349dbc7Sjsg }
481c349dbc7Sjsg
fail_and_restart_in_ms(uint16_t time,enum mod_hdcp_status * status,struct mod_hdcp_output * output)482c349dbc7Sjsg static inline void fail_and_restart_in_ms(uint16_t time,
483c349dbc7Sjsg enum mod_hdcp_status *status,
484c349dbc7Sjsg struct mod_hdcp_output *output)
485c349dbc7Sjsg {
486c349dbc7Sjsg output->callback_needed = 1;
487c349dbc7Sjsg output->callback_delay = time;
488c349dbc7Sjsg output->watchdog_timer_needed = 0;
489c349dbc7Sjsg output->watchdog_timer_delay = 0;
490c349dbc7Sjsg *status = MOD_HDCP_STATUS_RESET_NEEDED;
491c349dbc7Sjsg }
492c349dbc7Sjsg
callback_in_ms(uint16_t time,struct mod_hdcp_output * output)493c349dbc7Sjsg static inline void callback_in_ms(uint16_t time, struct mod_hdcp_output *output)
494c349dbc7Sjsg {
495c349dbc7Sjsg output->callback_needed = 1;
496c349dbc7Sjsg output->callback_delay = time;
497c349dbc7Sjsg }
498c349dbc7Sjsg
set_watchdog_in_ms(struct mod_hdcp * hdcp,uint16_t time,struct mod_hdcp_output * output)499c349dbc7Sjsg static inline void set_watchdog_in_ms(struct mod_hdcp *hdcp, uint16_t time,
500c349dbc7Sjsg struct mod_hdcp_output *output)
501c349dbc7Sjsg {
502c349dbc7Sjsg output->watchdog_timer_needed = 1;
503c349dbc7Sjsg output->watchdog_timer_delay = time;
504c349dbc7Sjsg }
505c349dbc7Sjsg
set_auth_complete(struct mod_hdcp * hdcp,struct mod_hdcp_output * output)5065ca02815Sjsg static inline void set_auth_complete(struct mod_hdcp *hdcp,
5075ca02815Sjsg struct mod_hdcp_output *output)
5085ca02815Sjsg {
5095ca02815Sjsg output->auth_complete = 1;
5105ca02815Sjsg mod_hdcp_log_ddc_trace(hdcp);
5115ca02815Sjsg }
5125ca02815Sjsg
513c349dbc7Sjsg /* connection topology helpers */
is_display_active(struct mod_hdcp_display * display)514c349dbc7Sjsg static inline uint8_t is_display_active(struct mod_hdcp_display *display)
515c349dbc7Sjsg {
516c349dbc7Sjsg return display->state >= MOD_HDCP_DISPLAY_ACTIVE;
517c349dbc7Sjsg }
518c349dbc7Sjsg
is_display_encryption_enabled(struct mod_hdcp_display * display)519c349dbc7Sjsg static inline uint8_t is_display_encryption_enabled(struct mod_hdcp_display *display)
520c349dbc7Sjsg {
521c349dbc7Sjsg return display->state >= MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED;
522c349dbc7Sjsg }
523c349dbc7Sjsg
get_active_display_count(struct mod_hdcp * hdcp)524c349dbc7Sjsg static inline uint8_t get_active_display_count(struct mod_hdcp *hdcp)
525c349dbc7Sjsg {
526ad8b1aafSjsg uint8_t active_count = 0;
527c349dbc7Sjsg uint8_t i;
528c349dbc7Sjsg
529c349dbc7Sjsg for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++)
530c349dbc7Sjsg if (is_display_active(&hdcp->displays[i]))
531ad8b1aafSjsg active_count++;
532ad8b1aafSjsg return active_count;
533c349dbc7Sjsg }
534c349dbc7Sjsg
get_first_active_display(struct mod_hdcp * hdcp)535ad8b1aafSjsg static inline struct mod_hdcp_display *get_first_active_display(
536c349dbc7Sjsg struct mod_hdcp *hdcp)
537c349dbc7Sjsg {
538c349dbc7Sjsg uint8_t i;
539c349dbc7Sjsg struct mod_hdcp_display *display = NULL;
540c349dbc7Sjsg
541c349dbc7Sjsg for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++)
542ad8b1aafSjsg if (is_display_active(&hdcp->displays[i])) {
543c349dbc7Sjsg display = &hdcp->displays[i];
544c349dbc7Sjsg break;
545c349dbc7Sjsg }
546c349dbc7Sjsg return display;
547c349dbc7Sjsg }
548c349dbc7Sjsg
get_active_display_at_index(struct mod_hdcp * hdcp,uint8_t index)549c349dbc7Sjsg static inline struct mod_hdcp_display *get_active_display_at_index(
550c349dbc7Sjsg struct mod_hdcp *hdcp, uint8_t index)
551c349dbc7Sjsg {
552c349dbc7Sjsg uint8_t i;
553c349dbc7Sjsg struct mod_hdcp_display *display = NULL;
554c349dbc7Sjsg
555c349dbc7Sjsg for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++)
556c349dbc7Sjsg if (hdcp->displays[i].index == index &&
557c349dbc7Sjsg is_display_active(&hdcp->displays[i])) {
558c349dbc7Sjsg display = &hdcp->displays[i];
559c349dbc7Sjsg break;
560c349dbc7Sjsg }
561c349dbc7Sjsg return display;
562c349dbc7Sjsg }
563c349dbc7Sjsg
get_empty_display_container(struct mod_hdcp * hdcp)564c349dbc7Sjsg static inline struct mod_hdcp_display *get_empty_display_container(
565c349dbc7Sjsg struct mod_hdcp *hdcp)
566c349dbc7Sjsg {
567c349dbc7Sjsg uint8_t i;
568c349dbc7Sjsg struct mod_hdcp_display *display = NULL;
569c349dbc7Sjsg
570c349dbc7Sjsg for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++)
571c349dbc7Sjsg if (!is_display_active(&hdcp->displays[i])) {
572c349dbc7Sjsg display = &hdcp->displays[i];
573c349dbc7Sjsg break;
574c349dbc7Sjsg }
575c349dbc7Sjsg return display;
576c349dbc7Sjsg }
577c349dbc7Sjsg
reset_retry_counts(struct mod_hdcp * hdcp)578c349dbc7Sjsg static inline void reset_retry_counts(struct mod_hdcp *hdcp)
579c349dbc7Sjsg {
580c349dbc7Sjsg hdcp->connection.hdcp1_retry_count = 0;
581c349dbc7Sjsg hdcp->connection.hdcp2_retry_count = 0;
582c349dbc7Sjsg }
583c349dbc7Sjsg
584c349dbc7Sjsg #endif /* HDCP_H_ */
585