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