Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2019 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  * Authors: AMD
0023  *
0024  */
0025 
0026 #include "hdcp.h"
0027 
0028 #define MIN(a, b) ((a) < (b) ? (a) : (b))
0029 #define HDCP_I2C_ADDR 0x3a  /* 0x74 >> 1*/
0030 #define KSV_READ_SIZE 0xf   /* 0x6803b - 0x6802c */
0031 #define HDCP_MAX_AUX_TRANSACTION_SIZE 16
0032 
0033 #define DP_CP_IRQ (1 << 2)
0034 
0035 enum mod_hdcp_ddc_message_id {
0036     MOD_HDCP_MESSAGE_ID_INVALID = -1,
0037 
0038     /* HDCP 1.4 */
0039 
0040     MOD_HDCP_MESSAGE_ID_READ_BKSV = 0,
0041     MOD_HDCP_MESSAGE_ID_READ_RI_R0,
0042     MOD_HDCP_MESSAGE_ID_WRITE_AKSV,
0043     MOD_HDCP_MESSAGE_ID_WRITE_AINFO,
0044     MOD_HDCP_MESSAGE_ID_WRITE_AN,
0045     MOD_HDCP_MESSAGE_ID_READ_VH_X,
0046     MOD_HDCP_MESSAGE_ID_READ_VH_0,
0047     MOD_HDCP_MESSAGE_ID_READ_VH_1,
0048     MOD_HDCP_MESSAGE_ID_READ_VH_2,
0049     MOD_HDCP_MESSAGE_ID_READ_VH_3,
0050     MOD_HDCP_MESSAGE_ID_READ_VH_4,
0051     MOD_HDCP_MESSAGE_ID_READ_BCAPS,
0052     MOD_HDCP_MESSAGE_ID_READ_BSTATUS,
0053     MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO,
0054     MOD_HDCP_MESSAGE_ID_READ_BINFO,
0055 
0056     /* HDCP 2.2 */
0057 
0058     MOD_HDCP_MESSAGE_ID_HDCP2VERSION,
0059     MOD_HDCP_MESSAGE_ID_RX_CAPS,
0060     MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT,
0061     MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT,
0062     MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM,
0063     MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM,
0064     MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME,
0065     MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO,
0066     MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT,
0067     MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME,
0068     MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS,
0069     MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST,
0070     MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2,
0071     MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK,
0072     MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE,
0073     MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY,
0074     MOD_HDCP_MESSAGE_ID_READ_RXSTATUS,
0075     MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE,
0076 
0077     MOD_HDCP_MESSAGE_ID_MAX
0078 };
0079 
0080 static const uint8_t hdcp_i2c_offsets[] = {
0081     [MOD_HDCP_MESSAGE_ID_READ_BKSV] = 0x0,
0082     [MOD_HDCP_MESSAGE_ID_READ_RI_R0] = 0x8,
0083     [MOD_HDCP_MESSAGE_ID_WRITE_AKSV] = 0x10,
0084     [MOD_HDCP_MESSAGE_ID_WRITE_AINFO] = 0x15,
0085     [MOD_HDCP_MESSAGE_ID_WRITE_AN] = 0x18,
0086     [MOD_HDCP_MESSAGE_ID_READ_VH_X] = 0x20,
0087     [MOD_HDCP_MESSAGE_ID_READ_VH_0] = 0x20,
0088     [MOD_HDCP_MESSAGE_ID_READ_VH_1] = 0x24,
0089     [MOD_HDCP_MESSAGE_ID_READ_VH_2] = 0x28,
0090     [MOD_HDCP_MESSAGE_ID_READ_VH_3] = 0x2C,
0091     [MOD_HDCP_MESSAGE_ID_READ_VH_4] = 0x30,
0092     [MOD_HDCP_MESSAGE_ID_READ_BCAPS] = 0x40,
0093     [MOD_HDCP_MESSAGE_ID_READ_BSTATUS] = 0x41,
0094     [MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO] = 0x43,
0095     [MOD_HDCP_MESSAGE_ID_READ_BINFO] = 0xFF,
0096     [MOD_HDCP_MESSAGE_ID_HDCP2VERSION] = 0x50,
0097     [MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT] = 0x60,
0098     [MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT] = 0x80,
0099     [MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM] = 0x60,
0100     [MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM] = 0x60,
0101     [MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME] = 0x80,
0102     [MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO] = 0x80,
0103     [MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT] = 0x60,
0104     [MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = 0x80,
0105     [MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = 0x60,
0106     [MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = 0x80,
0107     [MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2] = 0x80,
0108     [MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = 0x60,
0109     [MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = 0x60,
0110     [MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = 0x80,
0111     [MOD_HDCP_MESSAGE_ID_READ_RXSTATUS] = 0x70,
0112     [MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = 0x0
0113 };
0114 
0115 static const uint32_t hdcp_dpcd_addrs[] = {
0116     [MOD_HDCP_MESSAGE_ID_READ_BKSV] = 0x68000,
0117     [MOD_HDCP_MESSAGE_ID_READ_RI_R0] = 0x68005,
0118     [MOD_HDCP_MESSAGE_ID_WRITE_AKSV] = 0x68007,
0119     [MOD_HDCP_MESSAGE_ID_WRITE_AINFO] = 0x6803B,
0120     [MOD_HDCP_MESSAGE_ID_WRITE_AN] = 0x6800c,
0121     [MOD_HDCP_MESSAGE_ID_READ_VH_X] = 0x68014,
0122     [MOD_HDCP_MESSAGE_ID_READ_VH_0] = 0x68014,
0123     [MOD_HDCP_MESSAGE_ID_READ_VH_1] = 0x68018,
0124     [MOD_HDCP_MESSAGE_ID_READ_VH_2] = 0x6801c,
0125     [MOD_HDCP_MESSAGE_ID_READ_VH_3] = 0x68020,
0126     [MOD_HDCP_MESSAGE_ID_READ_VH_4] = 0x68024,
0127     [MOD_HDCP_MESSAGE_ID_READ_BCAPS] = 0x68028,
0128     [MOD_HDCP_MESSAGE_ID_READ_BSTATUS] = 0x68029,
0129     [MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO] = 0x6802c,
0130     [MOD_HDCP_MESSAGE_ID_READ_BINFO] = 0x6802a,
0131     [MOD_HDCP_MESSAGE_ID_RX_CAPS] = 0x6921d,
0132     [MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT] = 0x69000,
0133     [MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT] = 0x6900b,
0134     [MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM] = 0x69220,
0135     [MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM] = 0x692a0,
0136     [MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME] = 0x692c0,
0137     [MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO] = 0x692e0,
0138     [MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT] = 0x692f0,
0139     [MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = 0x692f8,
0140     [MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = 0x69318,
0141     [MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = 0x69330,
0142     [MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2] = 0x69340,
0143     [MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = 0x693e0,
0144     [MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = 0x693f0,
0145     [MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = 0x69473,
0146     [MOD_HDCP_MESSAGE_ID_READ_RXSTATUS] = 0x69493,
0147     [MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = 0x69494
0148 };
0149 
0150 static enum mod_hdcp_status read(struct mod_hdcp *hdcp,
0151         enum mod_hdcp_ddc_message_id msg_id,
0152         uint8_t *buf,
0153         uint32_t buf_len)
0154 {
0155     bool success = true;
0156     uint32_t cur_size = 0;
0157     uint32_t data_offset = 0;
0158 
0159     if (is_dp_hdcp(hdcp)) {
0160         while (buf_len > 0) {
0161             cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE);
0162             success = hdcp->config.ddc.funcs.read_dpcd(hdcp->config.ddc.handle,
0163                     hdcp_dpcd_addrs[msg_id] + data_offset,
0164                     buf + data_offset,
0165                     cur_size);
0166 
0167             if (!success)
0168                 break;
0169 
0170             buf_len -= cur_size;
0171             data_offset += cur_size;
0172         }
0173     } else {
0174         success = hdcp->config.ddc.funcs.read_i2c(
0175                 hdcp->config.ddc.handle,
0176                 HDCP_I2C_ADDR,
0177                 hdcp_i2c_offsets[msg_id],
0178                 buf,
0179                 (uint32_t)buf_len);
0180     }
0181 
0182     return success ? MOD_HDCP_STATUS_SUCCESS : MOD_HDCP_STATUS_DDC_FAILURE;
0183 }
0184 
0185 static enum mod_hdcp_status read_repeatedly(struct mod_hdcp *hdcp,
0186         enum mod_hdcp_ddc_message_id msg_id,
0187         uint8_t *buf,
0188         uint32_t buf_len,
0189         uint8_t read_size)
0190 {
0191     enum mod_hdcp_status status = MOD_HDCP_STATUS_DDC_FAILURE;
0192     uint32_t cur_size = 0;
0193     uint32_t data_offset = 0;
0194 
0195     while (buf_len > 0) {
0196         cur_size = MIN(buf_len, read_size);
0197         status = read(hdcp, msg_id, buf + data_offset, cur_size);
0198 
0199         if (status != MOD_HDCP_STATUS_SUCCESS)
0200             break;
0201 
0202         buf_len -= cur_size;
0203         data_offset += cur_size;
0204     }
0205 
0206     return status;
0207 }
0208 
0209 static enum mod_hdcp_status write(struct mod_hdcp *hdcp,
0210         enum mod_hdcp_ddc_message_id msg_id,
0211         uint8_t *buf,
0212         uint32_t buf_len)
0213 {
0214     bool success = true;
0215     uint32_t cur_size = 0;
0216     uint32_t data_offset = 0;
0217 
0218     if (is_dp_hdcp(hdcp)) {
0219         while (buf_len > 0) {
0220             cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE);
0221             success = hdcp->config.ddc.funcs.write_dpcd(
0222                     hdcp->config.ddc.handle,
0223                     hdcp_dpcd_addrs[msg_id] + data_offset,
0224                     buf + data_offset,
0225                     cur_size);
0226 
0227             if (!success)
0228                 break;
0229 
0230             buf_len -= cur_size;
0231             data_offset += cur_size;
0232         }
0233     } else {
0234         hdcp->buf[0] = hdcp_i2c_offsets[msg_id];
0235         memmove(&hdcp->buf[1], buf, buf_len);
0236         success = hdcp->config.ddc.funcs.write_i2c(
0237                 hdcp->config.ddc.handle,
0238                 HDCP_I2C_ADDR,
0239                 hdcp->buf,
0240                 (uint32_t)(buf_len+1));
0241     }
0242 
0243     return success ? MOD_HDCP_STATUS_SUCCESS : MOD_HDCP_STATUS_DDC_FAILURE;
0244 }
0245 
0246 enum mod_hdcp_status mod_hdcp_read_bksv(struct mod_hdcp *hdcp)
0247 {
0248     return read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BKSV,
0249             hdcp->auth.msg.hdcp1.bksv,
0250             sizeof(hdcp->auth.msg.hdcp1.bksv));
0251 }
0252 
0253 enum mod_hdcp_status mod_hdcp_read_bcaps(struct mod_hdcp *hdcp)
0254 {
0255     return read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BCAPS,
0256             &hdcp->auth.msg.hdcp1.bcaps,
0257             sizeof(hdcp->auth.msg.hdcp1.bcaps));
0258 }
0259 
0260 enum mod_hdcp_status mod_hdcp_read_bstatus(struct mod_hdcp *hdcp)
0261 {
0262     enum mod_hdcp_status status;
0263 
0264     if (is_dp_hdcp(hdcp))
0265         status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BSTATUS,
0266                     (uint8_t *)&hdcp->auth.msg.hdcp1.bstatus,
0267                     1);
0268     else
0269         status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BSTATUS,
0270                 (uint8_t *)&hdcp->auth.msg.hdcp1.bstatus,
0271                 sizeof(hdcp->auth.msg.hdcp1.bstatus));
0272     return status;
0273 }
0274 
0275 enum mod_hdcp_status mod_hdcp_read_r0p(struct mod_hdcp *hdcp)
0276 {
0277     return read(hdcp, MOD_HDCP_MESSAGE_ID_READ_RI_R0,
0278             (uint8_t *)&hdcp->auth.msg.hdcp1.r0p,
0279             sizeof(hdcp->auth.msg.hdcp1.r0p));
0280 }
0281 
0282 /* special case, reading repeatedly at the same address, don't use read() */
0283 enum mod_hdcp_status mod_hdcp_read_ksvlist(struct mod_hdcp *hdcp)
0284 {
0285     enum mod_hdcp_status status;
0286 
0287     if (is_dp_hdcp(hdcp))
0288         status = read_repeatedly(hdcp, MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO,
0289                 hdcp->auth.msg.hdcp1.ksvlist,
0290                 hdcp->auth.msg.hdcp1.ksvlist_size,
0291                 KSV_READ_SIZE);
0292     else
0293         status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO,
0294                 (uint8_t *)&hdcp->auth.msg.hdcp1.ksvlist,
0295                 hdcp->auth.msg.hdcp1.ksvlist_size);
0296     return status;
0297 }
0298 
0299 enum mod_hdcp_status mod_hdcp_read_vp(struct mod_hdcp *hdcp)
0300 {
0301     enum mod_hdcp_status status;
0302 
0303     status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_0,
0304             &hdcp->auth.msg.hdcp1.vp[0], 4);
0305     if (status != MOD_HDCP_STATUS_SUCCESS)
0306         goto out;
0307 
0308     status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_1,
0309             &hdcp->auth.msg.hdcp1.vp[4], 4);
0310     if (status != MOD_HDCP_STATUS_SUCCESS)
0311         goto out;
0312 
0313     status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_2,
0314             &hdcp->auth.msg.hdcp1.vp[8], 4);
0315     if (status != MOD_HDCP_STATUS_SUCCESS)
0316         goto out;
0317 
0318     status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_3,
0319             &hdcp->auth.msg.hdcp1.vp[12], 4);
0320     if (status != MOD_HDCP_STATUS_SUCCESS)
0321         goto out;
0322 
0323     status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_4,
0324             &hdcp->auth.msg.hdcp1.vp[16], 4);
0325 out:
0326     return status;
0327 }
0328 
0329 enum mod_hdcp_status mod_hdcp_read_binfo(struct mod_hdcp *hdcp)
0330 {
0331     enum mod_hdcp_status status;
0332 
0333     if (is_dp_hdcp(hdcp))
0334         status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BINFO,
0335                 (uint8_t *)&hdcp->auth.msg.hdcp1.binfo_dp,
0336                 sizeof(hdcp->auth.msg.hdcp1.binfo_dp));
0337     else
0338         status = MOD_HDCP_STATUS_INVALID_OPERATION;
0339 
0340     return status;
0341 }
0342 
0343 enum mod_hdcp_status mod_hdcp_write_aksv(struct mod_hdcp *hdcp)
0344 {
0345     return write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKSV,
0346             hdcp->auth.msg.hdcp1.aksv,
0347             sizeof(hdcp->auth.msg.hdcp1.aksv));
0348 }
0349 
0350 enum mod_hdcp_status mod_hdcp_write_ainfo(struct mod_hdcp *hdcp)
0351 {
0352     return write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AINFO,
0353             &hdcp->auth.msg.hdcp1.ainfo,
0354             sizeof(hdcp->auth.msg.hdcp1.ainfo));
0355 }
0356 
0357 enum mod_hdcp_status mod_hdcp_write_an(struct mod_hdcp *hdcp)
0358 {
0359     return write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AN,
0360             hdcp->auth.msg.hdcp1.an,
0361             sizeof(hdcp->auth.msg.hdcp1.an));
0362 }
0363 
0364 enum mod_hdcp_status mod_hdcp_read_hdcp2version(struct mod_hdcp *hdcp)
0365 {
0366     enum mod_hdcp_status status;
0367 
0368     if (is_dp_hdcp(hdcp))
0369         status = MOD_HDCP_STATUS_INVALID_OPERATION;
0370     else
0371         status = read(hdcp, MOD_HDCP_MESSAGE_ID_HDCP2VERSION,
0372                 &hdcp->auth.msg.hdcp2.hdcp2version_hdmi,
0373                 sizeof(hdcp->auth.msg.hdcp2.hdcp2version_hdmi));
0374 
0375     return status;
0376 }
0377 
0378 enum mod_hdcp_status mod_hdcp_read_rxcaps(struct mod_hdcp *hdcp)
0379 {
0380     enum mod_hdcp_status status;
0381 
0382     if (!is_dp_hdcp(hdcp))
0383         status = MOD_HDCP_STATUS_INVALID_OPERATION;
0384     else
0385         status = read(hdcp, MOD_HDCP_MESSAGE_ID_RX_CAPS,
0386                 hdcp->auth.msg.hdcp2.rxcaps_dp,
0387                 sizeof(hdcp->auth.msg.hdcp2.rxcaps_dp));
0388 
0389     return status;
0390 }
0391 
0392 enum mod_hdcp_status mod_hdcp_read_rxstatus(struct mod_hdcp *hdcp)
0393 {
0394     enum mod_hdcp_status status;
0395 
0396     if (is_dp_hdcp(hdcp)) {
0397         status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_RXSTATUS,
0398                 &hdcp->auth.msg.hdcp2.rxstatus_dp,
0399                 1);
0400     } else {
0401         status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_RXSTATUS,
0402                     (uint8_t *)&hdcp->auth.msg.hdcp2.rxstatus,
0403                     sizeof(hdcp->auth.msg.hdcp2.rxstatus));
0404     }
0405     return status;
0406 }
0407 
0408 enum mod_hdcp_status mod_hdcp_read_ake_cert(struct mod_hdcp *hdcp)
0409 {
0410     enum mod_hdcp_status status;
0411 
0412     if (is_dp_hdcp(hdcp)) {
0413         hdcp->auth.msg.hdcp2.ake_cert[0] = HDCP_2_2_AKE_SEND_CERT;
0414         status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT,
0415                 hdcp->auth.msg.hdcp2.ake_cert+1,
0416                 sizeof(hdcp->auth.msg.hdcp2.ake_cert)-1);
0417 
0418     } else {
0419         status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT,
0420                     hdcp->auth.msg.hdcp2.ake_cert,
0421                     sizeof(hdcp->auth.msg.hdcp2.ake_cert));
0422     }
0423     return status;
0424 }
0425 
0426 enum mod_hdcp_status mod_hdcp_read_h_prime(struct mod_hdcp *hdcp)
0427 {
0428     enum mod_hdcp_status status;
0429 
0430     if (is_dp_hdcp(hdcp)) {
0431         hdcp->auth.msg.hdcp2.ake_h_prime[0] = HDCP_2_2_AKE_SEND_HPRIME;
0432         status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME,
0433                 hdcp->auth.msg.hdcp2.ake_h_prime+1,
0434                 sizeof(hdcp->auth.msg.hdcp2.ake_h_prime)-1);
0435 
0436     } else {
0437         status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME,
0438                 hdcp->auth.msg.hdcp2.ake_h_prime,
0439                 sizeof(hdcp->auth.msg.hdcp2.ake_h_prime));
0440     }
0441     return status;
0442 }
0443 
0444 enum mod_hdcp_status mod_hdcp_read_pairing_info(struct mod_hdcp *hdcp)
0445 {
0446     enum mod_hdcp_status status;
0447 
0448     if (is_dp_hdcp(hdcp)) {
0449         hdcp->auth.msg.hdcp2.ake_pairing_info[0] = HDCP_2_2_AKE_SEND_PAIRING_INFO;
0450         status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO,
0451                 hdcp->auth.msg.hdcp2.ake_pairing_info+1,
0452                 sizeof(hdcp->auth.msg.hdcp2.ake_pairing_info)-1);
0453 
0454     } else {
0455         status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO,
0456                 hdcp->auth.msg.hdcp2.ake_pairing_info,
0457                 sizeof(hdcp->auth.msg.hdcp2.ake_pairing_info));
0458     }
0459     return status;
0460 }
0461 
0462 enum mod_hdcp_status mod_hdcp_read_l_prime(struct mod_hdcp *hdcp)
0463 {
0464     enum mod_hdcp_status status;
0465 
0466     if (is_dp_hdcp(hdcp)) {
0467         hdcp->auth.msg.hdcp2.lc_l_prime[0] = HDCP_2_2_LC_SEND_LPRIME;
0468         status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME,
0469                 hdcp->auth.msg.hdcp2.lc_l_prime+1,
0470                 sizeof(hdcp->auth.msg.hdcp2.lc_l_prime)-1);
0471 
0472     } else {
0473         status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME,
0474                 hdcp->auth.msg.hdcp2.lc_l_prime,
0475                 sizeof(hdcp->auth.msg.hdcp2.lc_l_prime));
0476     }
0477     return status;
0478 }
0479 
0480 enum mod_hdcp_status mod_hdcp_read_rx_id_list(struct mod_hdcp *hdcp)
0481 {
0482     enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
0483 
0484     if (is_dp_hdcp(hdcp)) {
0485         uint32_t device_count = 0;
0486         uint32_t rx_id_list_size = 0;
0487         uint32_t bytes_read = 0;
0488 
0489         hdcp->auth.msg.hdcp2.rx_id_list[0] = HDCP_2_2_REP_SEND_RECVID_LIST;
0490         status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST,
0491                         hdcp->auth.msg.hdcp2.rx_id_list+1,
0492                         HDCP_MAX_AUX_TRANSACTION_SIZE);
0493         if (status == MOD_HDCP_STATUS_SUCCESS) {
0494             bytes_read = HDCP_MAX_AUX_TRANSACTION_SIZE;
0495             device_count = HDCP_2_2_DEV_COUNT_LO(hdcp->auth.msg.hdcp2.rx_id_list[2]) +
0496                     (HDCP_2_2_DEV_COUNT_HI(hdcp->auth.msg.hdcp2.rx_id_list[1]) << 4);
0497             rx_id_list_size = MIN((21 + 5 * device_count),
0498                     (sizeof(hdcp->auth.msg.hdcp2.rx_id_list) - 1));
0499             status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2,
0500                     hdcp->auth.msg.hdcp2.rx_id_list + 1 + bytes_read,
0501                     (rx_id_list_size - 1) / HDCP_MAX_AUX_TRANSACTION_SIZE * HDCP_MAX_AUX_TRANSACTION_SIZE);
0502         }
0503     } else {
0504         status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST,
0505                 hdcp->auth.msg.hdcp2.rx_id_list,
0506                 hdcp->auth.msg.hdcp2.rx_id_list_size);
0507     }
0508     return status;
0509 }
0510 
0511 enum mod_hdcp_status mod_hdcp_read_stream_ready(struct mod_hdcp *hdcp)
0512 {
0513     enum mod_hdcp_status status;
0514 
0515     if (is_dp_hdcp(hdcp)) {
0516         hdcp->auth.msg.hdcp2.repeater_auth_stream_ready[0] = HDCP_2_2_REP_STREAM_READY;
0517         status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY,
0518                 hdcp->auth.msg.hdcp2.repeater_auth_stream_ready+1,
0519                 sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready)-1);
0520 
0521     } else {
0522         status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY,
0523                 hdcp->auth.msg.hdcp2.repeater_auth_stream_ready,
0524                 sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready));
0525     }
0526     return status;
0527 }
0528 
0529 enum mod_hdcp_status mod_hdcp_write_ake_init(struct mod_hdcp *hdcp)
0530 {
0531     enum mod_hdcp_status status;
0532 
0533     if (is_dp_hdcp(hdcp))
0534         status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT,
0535                 hdcp->auth.msg.hdcp2.ake_init+1,
0536                 sizeof(hdcp->auth.msg.hdcp2.ake_init)-1);
0537     else
0538         status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT,
0539                     hdcp->auth.msg.hdcp2.ake_init,
0540                     sizeof(hdcp->auth.msg.hdcp2.ake_init));
0541     return status;
0542 }
0543 
0544 enum mod_hdcp_status mod_hdcp_write_no_stored_km(struct mod_hdcp *hdcp)
0545 {
0546     enum mod_hdcp_status status;
0547 
0548     if (is_dp_hdcp(hdcp))
0549         status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM,
0550                 hdcp->auth.msg.hdcp2.ake_no_stored_km+1,
0551                 sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km)-1);
0552     else
0553         status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM,
0554             hdcp->auth.msg.hdcp2.ake_no_stored_km,
0555             sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km));
0556     return status;
0557 }
0558 
0559 enum mod_hdcp_status mod_hdcp_write_stored_km(struct mod_hdcp *hdcp)
0560 {
0561     enum mod_hdcp_status status;
0562 
0563     if (is_dp_hdcp(hdcp))
0564         status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM,
0565                 hdcp->auth.msg.hdcp2.ake_stored_km+1,
0566                 sizeof(hdcp->auth.msg.hdcp2.ake_stored_km)-1);
0567     else
0568         status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM,
0569                 hdcp->auth.msg.hdcp2.ake_stored_km,
0570                 sizeof(hdcp->auth.msg.hdcp2.ake_stored_km));
0571     return status;
0572 }
0573 
0574 enum mod_hdcp_status mod_hdcp_write_lc_init(struct mod_hdcp *hdcp)
0575 {
0576     enum mod_hdcp_status status;
0577 
0578     if (is_dp_hdcp(hdcp))
0579         status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT,
0580                 hdcp->auth.msg.hdcp2.lc_init+1,
0581                 sizeof(hdcp->auth.msg.hdcp2.lc_init)-1);
0582     else
0583         status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT,
0584                 hdcp->auth.msg.hdcp2.lc_init,
0585                 sizeof(hdcp->auth.msg.hdcp2.lc_init));
0586     return status;
0587 }
0588 
0589 enum mod_hdcp_status mod_hdcp_write_eks(struct mod_hdcp *hdcp)
0590 {
0591     enum mod_hdcp_status status;
0592 
0593     if (is_dp_hdcp(hdcp))
0594         status = write(hdcp,
0595                 MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS,
0596                 hdcp->auth.msg.hdcp2.ske_eks+1,
0597                 sizeof(hdcp->auth.msg.hdcp2.ske_eks)-1);
0598     else
0599         status = write(hdcp,
0600             MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS,
0601             hdcp->auth.msg.hdcp2.ske_eks,
0602             sizeof(hdcp->auth.msg.hdcp2.ske_eks));
0603     return status;
0604 }
0605 
0606 enum mod_hdcp_status mod_hdcp_write_repeater_auth_ack(struct mod_hdcp *hdcp)
0607 {
0608     enum mod_hdcp_status status;
0609 
0610     if (is_dp_hdcp(hdcp))
0611         status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK,
0612                 hdcp->auth.msg.hdcp2.repeater_auth_ack+1,
0613                 sizeof(hdcp->auth.msg.hdcp2.repeater_auth_ack)-1);
0614     else
0615         status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK,
0616                 hdcp->auth.msg.hdcp2.repeater_auth_ack,
0617                 sizeof(hdcp->auth.msg.hdcp2.repeater_auth_ack));
0618     return status;
0619 }
0620 
0621 enum mod_hdcp_status mod_hdcp_write_stream_manage(struct mod_hdcp *hdcp)
0622 {
0623     enum mod_hdcp_status status;
0624 
0625     if (is_dp_hdcp(hdcp))
0626         status = write(hdcp,
0627                 MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE,
0628                 hdcp->auth.msg.hdcp2.repeater_auth_stream_manage+1,
0629                 hdcp->auth.msg.hdcp2.stream_manage_size-1);
0630     else
0631         status = write(hdcp,
0632                 MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE,
0633                 hdcp->auth.msg.hdcp2.repeater_auth_stream_manage,
0634                 hdcp->auth.msg.hdcp2.stream_manage_size);
0635     return status;
0636 }
0637 
0638 enum mod_hdcp_status mod_hdcp_write_content_type(struct mod_hdcp *hdcp)
0639 {
0640     enum mod_hdcp_status status;
0641 
0642     if (is_dp_hdcp(hdcp))
0643         status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE,
0644                 hdcp->auth.msg.hdcp2.content_stream_type_dp+1,
0645                 sizeof(hdcp->auth.msg.hdcp2.content_stream_type_dp)-1);
0646     else
0647         status = MOD_HDCP_STATUS_INVALID_OPERATION;
0648     return status;
0649 }
0650 
0651 enum mod_hdcp_status mod_hdcp_clear_cp_irq_status(struct mod_hdcp *hdcp)
0652 {
0653     uint8_t clear_cp_irq_bit = DP_CP_IRQ;
0654     uint32_t size = 1;
0655 
0656     if (is_dp_hdcp(hdcp)) {
0657         uint32_t cp_irq_addrs = (hdcp->connection.link.dp.rev >= 0x14)
0658                 ? DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0:DP_DEVICE_SERVICE_IRQ_VECTOR;
0659         return hdcp->config.ddc.funcs.write_dpcd(hdcp->config.ddc.handle, cp_irq_addrs,
0660                 &clear_cp_irq_bit, size) ? MOD_HDCP_STATUS_SUCCESS : MOD_HDCP_STATUS_DDC_FAILURE;
0661     }
0662 
0663     return MOD_HDCP_STATUS_INVALID_OPERATION;
0664 }