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 #ifndef MIN 29 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 30 #endif 31 #define HDCP_I2C_ADDR 0x3a /* 0x74 >> 1*/ 32 #define KSV_READ_SIZE 0xf /* 0x6803b - 0x6802c */ 33 #define HDCP_MAX_AUX_TRANSACTION_SIZE 16 34 35 #define DP_CP_IRQ (1 << 2) 36 37 enum 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_MAX 80 }; 81 82 static 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] = 0x0 115 }; 116 117 static 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] = 0x69494 150 }; 151 152 static 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 199 static 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 223 static 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 272 enum 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 279 enum 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 286 enum 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 else 295 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 301 enum 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() */ 309 enum 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 else 319 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 325 enum 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); 351 out: 352 return status; 353 } 354 355 enum 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 else 364 status = MOD_HDCP_STATUS_INVALID_OPERATION; 365 366 return status; 367 } 368 369 enum 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 376 enum 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 383 enum 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 390 enum 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 else 397 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 404 enum 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 else 411 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 418 enum 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 434 enum 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 452 enum 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 470 enum 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 488 enum 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 506 enum 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 537 enum 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 555 enum 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 else 564 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 570 enum 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 else 579 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 585 enum 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 else 594 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 600 enum 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 else 609 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 615 enum 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 else 625 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 632 enum 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 else 641 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 647 enum 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 else 657 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 664 enum 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 else 673 status = MOD_HDCP_STATUS_INVALID_OPERATION; 674 return status; 675 } 676 677 enum 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