1 /*
2 * Copyright 2019 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 #define MIN(a, b) ((a) < (b) ? (a) : (b))
29 #define HDCP_I2C_ADDR 0x3a /* 0x74 >> 1*/
30 #define KSV_READ_SIZE 0xf /* 0x6803b - 0x6802c */
31 #define HDCP_MAX_AUX_TRANSACTION_SIZE 16
32
33 #define DP_CP_IRQ (1 << 2)
34
35 enum mod_hdcp_ddc_message_id {
36 MOD_HDCP_MESSAGE_ID_INVALID = -1,
37
38 /* HDCP 1.4 */
39
40 MOD_HDCP_MESSAGE_ID_READ_BKSV = 0,
41 MOD_HDCP_MESSAGE_ID_READ_RI_R0,
42 MOD_HDCP_MESSAGE_ID_WRITE_AKSV,
43 MOD_HDCP_MESSAGE_ID_WRITE_AINFO,
44 MOD_HDCP_MESSAGE_ID_WRITE_AN,
45 MOD_HDCP_MESSAGE_ID_READ_VH_X,
46 MOD_HDCP_MESSAGE_ID_READ_VH_0,
47 MOD_HDCP_MESSAGE_ID_READ_VH_1,
48 MOD_HDCP_MESSAGE_ID_READ_VH_2,
49 MOD_HDCP_MESSAGE_ID_READ_VH_3,
50 MOD_HDCP_MESSAGE_ID_READ_VH_4,
51 MOD_HDCP_MESSAGE_ID_READ_BCAPS,
52 MOD_HDCP_MESSAGE_ID_READ_BSTATUS,
53 MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO,
54 MOD_HDCP_MESSAGE_ID_READ_BINFO,
55
56 /* HDCP 2.2 */
57
58 MOD_HDCP_MESSAGE_ID_HDCP2VERSION,
59 MOD_HDCP_MESSAGE_ID_RX_CAPS,
60 MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT,
61 MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT,
62 MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM,
63 MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM,
64 MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME,
65 MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO,
66 MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT,
67 MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME,
68 MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS,
69 MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST,
70 MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2,
71 MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK,
72 MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE,
73 MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY,
74 MOD_HDCP_MESSAGE_ID_READ_RXSTATUS,
75 MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE,
76
77 MOD_HDCP_MESSAGE_ID_MAX
78 };
79
80 static const uint8_t hdcp_i2c_offsets[] = {
81 [MOD_HDCP_MESSAGE_ID_READ_BKSV] = 0x0,
82 [MOD_HDCP_MESSAGE_ID_READ_RI_R0] = 0x8,
83 [MOD_HDCP_MESSAGE_ID_WRITE_AKSV] = 0x10,
84 [MOD_HDCP_MESSAGE_ID_WRITE_AINFO] = 0x15,
85 [MOD_HDCP_MESSAGE_ID_WRITE_AN] = 0x18,
86 [MOD_HDCP_MESSAGE_ID_READ_VH_X] = 0x20,
87 [MOD_HDCP_MESSAGE_ID_READ_VH_0] = 0x20,
88 [MOD_HDCP_MESSAGE_ID_READ_VH_1] = 0x24,
89 [MOD_HDCP_MESSAGE_ID_READ_VH_2] = 0x28,
90 [MOD_HDCP_MESSAGE_ID_READ_VH_3] = 0x2C,
91 [MOD_HDCP_MESSAGE_ID_READ_VH_4] = 0x30,
92 [MOD_HDCP_MESSAGE_ID_READ_BCAPS] = 0x40,
93 [MOD_HDCP_MESSAGE_ID_READ_BSTATUS] = 0x41,
94 [MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO] = 0x43,
95 [MOD_HDCP_MESSAGE_ID_READ_BINFO] = 0xFF,
96 [MOD_HDCP_MESSAGE_ID_HDCP2VERSION] = 0x50,
97 [MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT] = 0x60,
98 [MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT] = 0x80,
99 [MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM] = 0x60,
100 [MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM] = 0x60,
101 [MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME] = 0x80,
102 [MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO] = 0x80,
103 [MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT] = 0x60,
104 [MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = 0x80,
105 [MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = 0x60,
106 [MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = 0x80,
107 [MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2] = 0x80,
108 [MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = 0x60,
109 [MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = 0x60,
110 [MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = 0x80,
111 [MOD_HDCP_MESSAGE_ID_READ_RXSTATUS] = 0x70,
112 [MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = 0x0
113 };
114
115 static const uint32_t hdcp_dpcd_addrs[] = {
116 [MOD_HDCP_MESSAGE_ID_READ_BKSV] = 0x68000,
117 [MOD_HDCP_MESSAGE_ID_READ_RI_R0] = 0x68005,
118 [MOD_HDCP_MESSAGE_ID_WRITE_AKSV] = 0x68007,
119 [MOD_HDCP_MESSAGE_ID_WRITE_AINFO] = 0x6803B,
120 [MOD_HDCP_MESSAGE_ID_WRITE_AN] = 0x6800c,
121 [MOD_HDCP_MESSAGE_ID_READ_VH_X] = 0x68014,
122 [MOD_HDCP_MESSAGE_ID_READ_VH_0] = 0x68014,
123 [MOD_HDCP_MESSAGE_ID_READ_VH_1] = 0x68018,
124 [MOD_HDCP_MESSAGE_ID_READ_VH_2] = 0x6801c,
125 [MOD_HDCP_MESSAGE_ID_READ_VH_3] = 0x68020,
126 [MOD_HDCP_MESSAGE_ID_READ_VH_4] = 0x68024,
127 [MOD_HDCP_MESSAGE_ID_READ_BCAPS] = 0x68028,
128 [MOD_HDCP_MESSAGE_ID_READ_BSTATUS] = 0x68029,
129 [MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO] = 0x6802c,
130 [MOD_HDCP_MESSAGE_ID_READ_BINFO] = 0x6802a,
131 [MOD_HDCP_MESSAGE_ID_RX_CAPS] = 0x6921d,
132 [MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT] = 0x69000,
133 [MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT] = 0x6900b,
134 [MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM] = 0x69220,
135 [MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM] = 0x692a0,
136 [MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME] = 0x692c0,
137 [MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO] = 0x692e0,
138 [MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT] = 0x692f0,
139 [MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = 0x692f8,
140 [MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = 0x69318,
141 [MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = 0x69330,
142 [MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2] = 0x69340,
143 [MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = 0x693e0,
144 [MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = 0x693f0,
145 [MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = 0x69473,
146 [MOD_HDCP_MESSAGE_ID_READ_RXSTATUS] = 0x69493,
147 [MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = 0x69494
148 };
149
read(struct mod_hdcp * hdcp,enum mod_hdcp_ddc_message_id msg_id,uint8_t * buf,uint32_t buf_len)150 static enum mod_hdcp_status read(struct mod_hdcp *hdcp,
151 enum mod_hdcp_ddc_message_id msg_id,
152 uint8_t *buf,
153 uint32_t buf_len)
154 {
155 bool success = true;
156 uint32_t cur_size = 0;
157 uint32_t data_offset = 0;
158
159 if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID) {
160 return MOD_HDCP_STATUS_DDC_FAILURE;
161 }
162
163 if (is_dp_hdcp(hdcp)) {
164 while (buf_len > 0) {
165 cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE);
166 success = hdcp->config.ddc.funcs.read_dpcd(hdcp->config.ddc.handle,
167 hdcp_dpcd_addrs[msg_id] + data_offset,
168 buf + data_offset,
169 cur_size);
170
171 if (!success)
172 break;
173
174 buf_len -= cur_size;
175 data_offset += cur_size;
176 }
177 } else {
178 success = hdcp->config.ddc.funcs.read_i2c(
179 hdcp->config.ddc.handle,
180 HDCP_I2C_ADDR,
181 hdcp_i2c_offsets[msg_id],
182 buf,
183 (uint32_t)buf_len);
184 }
185
186 return success ? MOD_HDCP_STATUS_SUCCESS : MOD_HDCP_STATUS_DDC_FAILURE;
187 }
188
read_repeatedly(struct mod_hdcp * hdcp,enum mod_hdcp_ddc_message_id msg_id,uint8_t * buf,uint32_t buf_len,uint8_t read_size)189 static enum mod_hdcp_status read_repeatedly(struct mod_hdcp *hdcp,
190 enum mod_hdcp_ddc_message_id msg_id,
191 uint8_t *buf,
192 uint32_t buf_len,
193 uint8_t read_size)
194 {
195 enum mod_hdcp_status status = MOD_HDCP_STATUS_DDC_FAILURE;
196 uint32_t cur_size = 0;
197 uint32_t data_offset = 0;
198
199 while (buf_len > 0) {
200 cur_size = MIN(buf_len, read_size);
201 status = read(hdcp, msg_id, buf + data_offset, cur_size);
202
203 if (status != MOD_HDCP_STATUS_SUCCESS)
204 break;
205
206 buf_len -= cur_size;
207 data_offset += cur_size;
208 }
209
210 return status;
211 }
212
write(struct mod_hdcp * hdcp,enum mod_hdcp_ddc_message_id msg_id,uint8_t * buf,uint32_t buf_len)213 static enum mod_hdcp_status write(struct mod_hdcp *hdcp,
214 enum mod_hdcp_ddc_message_id msg_id,
215 uint8_t *buf,
216 uint32_t buf_len)
217 {
218 bool success = true;
219 uint32_t cur_size = 0;
220 uint32_t data_offset = 0;
221
222 if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID) {
223 return MOD_HDCP_STATUS_DDC_FAILURE;
224 }
225
226 if (is_dp_hdcp(hdcp)) {
227 while (buf_len > 0) {
228 cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE);
229 success = hdcp->config.ddc.funcs.write_dpcd(
230 hdcp->config.ddc.handle,
231 hdcp_dpcd_addrs[msg_id] + data_offset,
232 buf + data_offset,
233 cur_size);
234
235 if (!success)
236 break;
237
238 buf_len -= cur_size;
239 data_offset += cur_size;
240 }
241 } else {
242 hdcp->buf[0] = hdcp_i2c_offsets[msg_id];
243 memmove(&hdcp->buf[1], buf, buf_len);
244 success = hdcp->config.ddc.funcs.write_i2c(
245 hdcp->config.ddc.handle,
246 HDCP_I2C_ADDR,
247 hdcp->buf,
248 (uint32_t)(buf_len+1));
249 }
250
251 return success ? MOD_HDCP_STATUS_SUCCESS : MOD_HDCP_STATUS_DDC_FAILURE;
252 }
253
mod_hdcp_read_bksv(struct mod_hdcp * hdcp)254 enum mod_hdcp_status mod_hdcp_read_bksv(struct mod_hdcp *hdcp)
255 {
256 return read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BKSV,
257 hdcp->auth.msg.hdcp1.bksv,
258 sizeof(hdcp->auth.msg.hdcp1.bksv));
259 }
260
mod_hdcp_read_bcaps(struct mod_hdcp * hdcp)261 enum mod_hdcp_status mod_hdcp_read_bcaps(struct mod_hdcp *hdcp)
262 {
263 return read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BCAPS,
264 &hdcp->auth.msg.hdcp1.bcaps,
265 sizeof(hdcp->auth.msg.hdcp1.bcaps));
266 }
267
mod_hdcp_read_bstatus(struct mod_hdcp * hdcp)268 enum mod_hdcp_status mod_hdcp_read_bstatus(struct mod_hdcp *hdcp)
269 {
270 enum mod_hdcp_status status;
271
272 if (is_dp_hdcp(hdcp))
273 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BSTATUS,
274 (uint8_t *)&hdcp->auth.msg.hdcp1.bstatus,
275 1);
276 else
277 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BSTATUS,
278 (uint8_t *)&hdcp->auth.msg.hdcp1.bstatus,
279 sizeof(hdcp->auth.msg.hdcp1.bstatus));
280 return status;
281 }
282
mod_hdcp_read_r0p(struct mod_hdcp * hdcp)283 enum mod_hdcp_status mod_hdcp_read_r0p(struct mod_hdcp *hdcp)
284 {
285 return read(hdcp, MOD_HDCP_MESSAGE_ID_READ_RI_R0,
286 (uint8_t *)&hdcp->auth.msg.hdcp1.r0p,
287 sizeof(hdcp->auth.msg.hdcp1.r0p));
288 }
289
290 /* special case, reading repeatedly at the same address, don't use read() */
mod_hdcp_read_ksvlist(struct mod_hdcp * hdcp)291 enum mod_hdcp_status mod_hdcp_read_ksvlist(struct mod_hdcp *hdcp)
292 {
293 enum mod_hdcp_status status;
294
295 if (is_dp_hdcp(hdcp))
296 status = read_repeatedly(hdcp, MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO,
297 hdcp->auth.msg.hdcp1.ksvlist,
298 hdcp->auth.msg.hdcp1.ksvlist_size,
299 KSV_READ_SIZE);
300 else
301 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO,
302 (uint8_t *)&hdcp->auth.msg.hdcp1.ksvlist,
303 hdcp->auth.msg.hdcp1.ksvlist_size);
304 return status;
305 }
306
mod_hdcp_read_vp(struct mod_hdcp * hdcp)307 enum mod_hdcp_status mod_hdcp_read_vp(struct mod_hdcp *hdcp)
308 {
309 enum mod_hdcp_status status;
310
311 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_0,
312 &hdcp->auth.msg.hdcp1.vp[0], 4);
313 if (status != MOD_HDCP_STATUS_SUCCESS)
314 goto out;
315
316 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_1,
317 &hdcp->auth.msg.hdcp1.vp[4], 4);
318 if (status != MOD_HDCP_STATUS_SUCCESS)
319 goto out;
320
321 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_2,
322 &hdcp->auth.msg.hdcp1.vp[8], 4);
323 if (status != MOD_HDCP_STATUS_SUCCESS)
324 goto out;
325
326 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_3,
327 &hdcp->auth.msg.hdcp1.vp[12], 4);
328 if (status != MOD_HDCP_STATUS_SUCCESS)
329 goto out;
330
331 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_4,
332 &hdcp->auth.msg.hdcp1.vp[16], 4);
333 out:
334 return status;
335 }
336
mod_hdcp_read_binfo(struct mod_hdcp * hdcp)337 enum mod_hdcp_status mod_hdcp_read_binfo(struct mod_hdcp *hdcp)
338 {
339 enum mod_hdcp_status status;
340
341 if (is_dp_hdcp(hdcp))
342 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BINFO,
343 (uint8_t *)&hdcp->auth.msg.hdcp1.binfo_dp,
344 sizeof(hdcp->auth.msg.hdcp1.binfo_dp));
345 else
346 status = MOD_HDCP_STATUS_INVALID_OPERATION;
347
348 return status;
349 }
350
mod_hdcp_write_aksv(struct mod_hdcp * hdcp)351 enum mod_hdcp_status mod_hdcp_write_aksv(struct mod_hdcp *hdcp)
352 {
353 return write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKSV,
354 hdcp->auth.msg.hdcp1.aksv,
355 sizeof(hdcp->auth.msg.hdcp1.aksv));
356 }
357
mod_hdcp_write_ainfo(struct mod_hdcp * hdcp)358 enum mod_hdcp_status mod_hdcp_write_ainfo(struct mod_hdcp *hdcp)
359 {
360 return write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AINFO,
361 &hdcp->auth.msg.hdcp1.ainfo,
362 sizeof(hdcp->auth.msg.hdcp1.ainfo));
363 }
364
mod_hdcp_write_an(struct mod_hdcp * hdcp)365 enum mod_hdcp_status mod_hdcp_write_an(struct mod_hdcp *hdcp)
366 {
367 return write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AN,
368 hdcp->auth.msg.hdcp1.an,
369 sizeof(hdcp->auth.msg.hdcp1.an));
370 }
371
mod_hdcp_read_hdcp2version(struct mod_hdcp * hdcp)372 enum mod_hdcp_status mod_hdcp_read_hdcp2version(struct mod_hdcp *hdcp)
373 {
374 enum mod_hdcp_status status;
375
376 if (is_dp_hdcp(hdcp))
377 status = MOD_HDCP_STATUS_INVALID_OPERATION;
378 else
379 status = read(hdcp, MOD_HDCP_MESSAGE_ID_HDCP2VERSION,
380 &hdcp->auth.msg.hdcp2.hdcp2version_hdmi,
381 sizeof(hdcp->auth.msg.hdcp2.hdcp2version_hdmi));
382
383 return status;
384 }
385
mod_hdcp_read_rxcaps(struct mod_hdcp * hdcp)386 enum mod_hdcp_status mod_hdcp_read_rxcaps(struct mod_hdcp *hdcp)
387 {
388 enum mod_hdcp_status status;
389
390 if (!is_dp_hdcp(hdcp))
391 status = MOD_HDCP_STATUS_INVALID_OPERATION;
392 else
393 status = read(hdcp, MOD_HDCP_MESSAGE_ID_RX_CAPS,
394 hdcp->auth.msg.hdcp2.rxcaps_dp,
395 sizeof(hdcp->auth.msg.hdcp2.rxcaps_dp));
396
397 return status;
398 }
399
mod_hdcp_read_rxstatus(struct mod_hdcp * hdcp)400 enum mod_hdcp_status mod_hdcp_read_rxstatus(struct mod_hdcp *hdcp)
401 {
402 enum mod_hdcp_status status;
403
404 if (is_dp_hdcp(hdcp)) {
405 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_RXSTATUS,
406 &hdcp->auth.msg.hdcp2.rxstatus_dp,
407 1);
408 } else {
409 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_RXSTATUS,
410 (uint8_t *)&hdcp->auth.msg.hdcp2.rxstatus,
411 sizeof(hdcp->auth.msg.hdcp2.rxstatus));
412 }
413 return status;
414 }
415
mod_hdcp_read_ake_cert(struct mod_hdcp * hdcp)416 enum mod_hdcp_status mod_hdcp_read_ake_cert(struct mod_hdcp *hdcp)
417 {
418 enum mod_hdcp_status status;
419
420 if (is_dp_hdcp(hdcp)) {
421 hdcp->auth.msg.hdcp2.ake_cert[0] = HDCP_2_2_AKE_SEND_CERT;
422 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT,
423 hdcp->auth.msg.hdcp2.ake_cert+1,
424 sizeof(hdcp->auth.msg.hdcp2.ake_cert)-1);
425
426 } else {
427 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT,
428 hdcp->auth.msg.hdcp2.ake_cert,
429 sizeof(hdcp->auth.msg.hdcp2.ake_cert));
430 }
431 return status;
432 }
433
mod_hdcp_read_h_prime(struct mod_hdcp * hdcp)434 enum mod_hdcp_status mod_hdcp_read_h_prime(struct mod_hdcp *hdcp)
435 {
436 enum mod_hdcp_status status;
437
438 if (is_dp_hdcp(hdcp)) {
439 hdcp->auth.msg.hdcp2.ake_h_prime[0] = HDCP_2_2_AKE_SEND_HPRIME;
440 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME,
441 hdcp->auth.msg.hdcp2.ake_h_prime+1,
442 sizeof(hdcp->auth.msg.hdcp2.ake_h_prime)-1);
443
444 } else {
445 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME,
446 hdcp->auth.msg.hdcp2.ake_h_prime,
447 sizeof(hdcp->auth.msg.hdcp2.ake_h_prime));
448 }
449 return status;
450 }
451
mod_hdcp_read_pairing_info(struct mod_hdcp * hdcp)452 enum mod_hdcp_status mod_hdcp_read_pairing_info(struct mod_hdcp *hdcp)
453 {
454 enum mod_hdcp_status status;
455
456 if (is_dp_hdcp(hdcp)) {
457 hdcp->auth.msg.hdcp2.ake_pairing_info[0] = HDCP_2_2_AKE_SEND_PAIRING_INFO;
458 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO,
459 hdcp->auth.msg.hdcp2.ake_pairing_info+1,
460 sizeof(hdcp->auth.msg.hdcp2.ake_pairing_info)-1);
461
462 } else {
463 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO,
464 hdcp->auth.msg.hdcp2.ake_pairing_info,
465 sizeof(hdcp->auth.msg.hdcp2.ake_pairing_info));
466 }
467 return status;
468 }
469
mod_hdcp_read_l_prime(struct mod_hdcp * hdcp)470 enum mod_hdcp_status mod_hdcp_read_l_prime(struct mod_hdcp *hdcp)
471 {
472 enum mod_hdcp_status status;
473
474 if (is_dp_hdcp(hdcp)) {
475 hdcp->auth.msg.hdcp2.lc_l_prime[0] = HDCP_2_2_LC_SEND_LPRIME;
476 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME,
477 hdcp->auth.msg.hdcp2.lc_l_prime+1,
478 sizeof(hdcp->auth.msg.hdcp2.lc_l_prime)-1);
479
480 } else {
481 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME,
482 hdcp->auth.msg.hdcp2.lc_l_prime,
483 sizeof(hdcp->auth.msg.hdcp2.lc_l_prime));
484 }
485 return status;
486 }
487
mod_hdcp_read_rx_id_list(struct mod_hdcp * hdcp)488 enum mod_hdcp_status mod_hdcp_read_rx_id_list(struct mod_hdcp *hdcp)
489 {
490 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
491
492 if (is_dp_hdcp(hdcp)) {
493 uint32_t device_count = 0;
494 uint32_t rx_id_list_size = 0;
495 uint32_t bytes_read = 0;
496
497 hdcp->auth.msg.hdcp2.rx_id_list[0] = HDCP_2_2_REP_SEND_RECVID_LIST;
498 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST,
499 hdcp->auth.msg.hdcp2.rx_id_list+1,
500 HDCP_MAX_AUX_TRANSACTION_SIZE);
501 if (status == MOD_HDCP_STATUS_SUCCESS) {
502 bytes_read = HDCP_MAX_AUX_TRANSACTION_SIZE;
503 device_count = HDCP_2_2_DEV_COUNT_LO(hdcp->auth.msg.hdcp2.rx_id_list[2]) +
504 (HDCP_2_2_DEV_COUNT_HI(hdcp->auth.msg.hdcp2.rx_id_list[1]) << 4);
505 rx_id_list_size = MIN((21 + 5 * device_count),
506 (sizeof(hdcp->auth.msg.hdcp2.rx_id_list) - 1));
507 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2,
508 hdcp->auth.msg.hdcp2.rx_id_list + 1 + bytes_read,
509 (rx_id_list_size - 1) / HDCP_MAX_AUX_TRANSACTION_SIZE * HDCP_MAX_AUX_TRANSACTION_SIZE);
510 }
511 } else {
512 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST,
513 hdcp->auth.msg.hdcp2.rx_id_list,
514 hdcp->auth.msg.hdcp2.rx_id_list_size);
515 }
516 return status;
517 }
518
mod_hdcp_read_stream_ready(struct mod_hdcp * hdcp)519 enum mod_hdcp_status mod_hdcp_read_stream_ready(struct mod_hdcp *hdcp)
520 {
521 enum mod_hdcp_status status;
522
523 if (is_dp_hdcp(hdcp)) {
524 hdcp->auth.msg.hdcp2.repeater_auth_stream_ready[0] = HDCP_2_2_REP_STREAM_READY;
525 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY,
526 hdcp->auth.msg.hdcp2.repeater_auth_stream_ready+1,
527 sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready)-1);
528
529 } else {
530 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY,
531 hdcp->auth.msg.hdcp2.repeater_auth_stream_ready,
532 sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready));
533 }
534 return status;
535 }
536
mod_hdcp_write_ake_init(struct mod_hdcp * hdcp)537 enum mod_hdcp_status mod_hdcp_write_ake_init(struct mod_hdcp *hdcp)
538 {
539 enum mod_hdcp_status status;
540
541 if (is_dp_hdcp(hdcp))
542 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT,
543 hdcp->auth.msg.hdcp2.ake_init+1,
544 sizeof(hdcp->auth.msg.hdcp2.ake_init)-1);
545 else
546 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT,
547 hdcp->auth.msg.hdcp2.ake_init,
548 sizeof(hdcp->auth.msg.hdcp2.ake_init));
549 return status;
550 }
551
mod_hdcp_write_no_stored_km(struct mod_hdcp * hdcp)552 enum mod_hdcp_status mod_hdcp_write_no_stored_km(struct mod_hdcp *hdcp)
553 {
554 enum mod_hdcp_status status;
555
556 if (is_dp_hdcp(hdcp))
557 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM,
558 hdcp->auth.msg.hdcp2.ake_no_stored_km+1,
559 sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km)-1);
560 else
561 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM,
562 hdcp->auth.msg.hdcp2.ake_no_stored_km,
563 sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km));
564 return status;
565 }
566
mod_hdcp_write_stored_km(struct mod_hdcp * hdcp)567 enum mod_hdcp_status mod_hdcp_write_stored_km(struct mod_hdcp *hdcp)
568 {
569 enum mod_hdcp_status status;
570
571 if (is_dp_hdcp(hdcp))
572 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM,
573 hdcp->auth.msg.hdcp2.ake_stored_km+1,
574 sizeof(hdcp->auth.msg.hdcp2.ake_stored_km)-1);
575 else
576 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM,
577 hdcp->auth.msg.hdcp2.ake_stored_km,
578 sizeof(hdcp->auth.msg.hdcp2.ake_stored_km));
579 return status;
580 }
581
mod_hdcp_write_lc_init(struct mod_hdcp * hdcp)582 enum mod_hdcp_status mod_hdcp_write_lc_init(struct mod_hdcp *hdcp)
583 {
584 enum mod_hdcp_status status;
585
586 if (is_dp_hdcp(hdcp))
587 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT,
588 hdcp->auth.msg.hdcp2.lc_init+1,
589 sizeof(hdcp->auth.msg.hdcp2.lc_init)-1);
590 else
591 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT,
592 hdcp->auth.msg.hdcp2.lc_init,
593 sizeof(hdcp->auth.msg.hdcp2.lc_init));
594 return status;
595 }
596
mod_hdcp_write_eks(struct mod_hdcp * hdcp)597 enum mod_hdcp_status mod_hdcp_write_eks(struct mod_hdcp *hdcp)
598 {
599 enum mod_hdcp_status status;
600
601 if (is_dp_hdcp(hdcp))
602 status = write(hdcp,
603 MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS,
604 hdcp->auth.msg.hdcp2.ske_eks+1,
605 sizeof(hdcp->auth.msg.hdcp2.ske_eks)-1);
606 else
607 status = write(hdcp,
608 MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS,
609 hdcp->auth.msg.hdcp2.ske_eks,
610 sizeof(hdcp->auth.msg.hdcp2.ske_eks));
611 return status;
612 }
613
mod_hdcp_write_repeater_auth_ack(struct mod_hdcp * hdcp)614 enum mod_hdcp_status mod_hdcp_write_repeater_auth_ack(struct mod_hdcp *hdcp)
615 {
616 enum mod_hdcp_status status;
617
618 if (is_dp_hdcp(hdcp))
619 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK,
620 hdcp->auth.msg.hdcp2.repeater_auth_ack+1,
621 sizeof(hdcp->auth.msg.hdcp2.repeater_auth_ack)-1);
622 else
623 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK,
624 hdcp->auth.msg.hdcp2.repeater_auth_ack,
625 sizeof(hdcp->auth.msg.hdcp2.repeater_auth_ack));
626 return status;
627 }
628
mod_hdcp_write_stream_manage(struct mod_hdcp * hdcp)629 enum mod_hdcp_status mod_hdcp_write_stream_manage(struct mod_hdcp *hdcp)
630 {
631 enum mod_hdcp_status status;
632
633 if (is_dp_hdcp(hdcp))
634 status = write(hdcp,
635 MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE,
636 hdcp->auth.msg.hdcp2.repeater_auth_stream_manage+1,
637 hdcp->auth.msg.hdcp2.stream_manage_size-1);
638 else
639 status = write(hdcp,
640 MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE,
641 hdcp->auth.msg.hdcp2.repeater_auth_stream_manage,
642 hdcp->auth.msg.hdcp2.stream_manage_size);
643 return status;
644 }
645
mod_hdcp_write_content_type(struct mod_hdcp * hdcp)646 enum mod_hdcp_status mod_hdcp_write_content_type(struct mod_hdcp *hdcp)
647 {
648 enum mod_hdcp_status status;
649
650 if (is_dp_hdcp(hdcp))
651 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE,
652 hdcp->auth.msg.hdcp2.content_stream_type_dp+1,
653 sizeof(hdcp->auth.msg.hdcp2.content_stream_type_dp)-1);
654 else
655 status = MOD_HDCP_STATUS_INVALID_OPERATION;
656 return status;
657 }
658
mod_hdcp_clear_cp_irq_status(struct mod_hdcp * hdcp)659 enum mod_hdcp_status mod_hdcp_clear_cp_irq_status(struct mod_hdcp *hdcp)
660 {
661 uint8_t clear_cp_irq_bit = DP_CP_IRQ;
662 uint32_t size = 1;
663
664 if (is_dp_hdcp(hdcp)) {
665 uint32_t cp_irq_addrs = (hdcp->connection.link.dp.rev >= 0x14)
666 ? DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0:DP_DEVICE_SERVICE_IRQ_VECTOR;
667 return hdcp->config.ddc.funcs.write_dpcd(hdcp->config.ddc.handle, cp_irq_addrs,
668 &clear_cp_irq_bit, size) ? MOD_HDCP_STATUS_SUCCESS : MOD_HDCP_STATUS_DDC_FAILURE;
669 }
670
671 return MOD_HDCP_STATUS_INVALID_OPERATION;
672 }
673