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