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 #ifdef __linux__ 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 = sizeof(hdcp_dpcd_addrs) / 167 sizeof(hdcp_dpcd_addrs[0]); 168 if (msg_id >= num_dpcd_addrs) 169 return MOD_HDCP_STATUS_DDC_FAILURE; 170 171 while (buf_len > 0) { 172 cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE); 173 success = hdcp->config.ddc.funcs.read_dpcd(hdcp->config.ddc.handle, 174 hdcp_dpcd_addrs[msg_id] + data_offset, 175 buf + data_offset, 176 cur_size); 177 178 if (!success) 179 break; 180 181 buf_len -= cur_size; 182 data_offset += cur_size; 183 } 184 } else { 185 int num_i2c_offsets = sizeof(hdcp_i2c_offsets) / 186 sizeof(hdcp_i2c_offsets[0]); 187 if (msg_id >= num_i2c_offsets) 188 return MOD_HDCP_STATUS_DDC_FAILURE; 189 190 success = hdcp->config.ddc.funcs.read_i2c( 191 hdcp->config.ddc.handle, 192 HDCP_I2C_ADDR, 193 hdcp_i2c_offsets[msg_id], 194 buf, 195 (uint32_t)buf_len); 196 } 197 198 return success ? MOD_HDCP_STATUS_SUCCESS : MOD_HDCP_STATUS_DDC_FAILURE; 199 } 200 201 static enum mod_hdcp_status read_repeatedly(struct mod_hdcp *hdcp, 202 enum mod_hdcp_ddc_message_id msg_id, 203 uint8_t *buf, 204 uint32_t buf_len, 205 uint8_t read_size) 206 { 207 enum mod_hdcp_status status = MOD_HDCP_STATUS_DDC_FAILURE; 208 uint32_t cur_size = 0; 209 uint32_t data_offset = 0; 210 211 while (buf_len > 0) { 212 cur_size = MIN(buf_len, read_size); 213 status = read(hdcp, msg_id, buf + data_offset, cur_size); 214 215 if (status != MOD_HDCP_STATUS_SUCCESS) 216 break; 217 218 buf_len -= cur_size; 219 data_offset += cur_size; 220 } 221 222 return status; 223 } 224 225 static enum mod_hdcp_status write(struct mod_hdcp *hdcp, 226 enum mod_hdcp_ddc_message_id msg_id, 227 uint8_t *buf, 228 uint32_t buf_len) 229 { 230 bool success = true; 231 uint32_t cur_size = 0; 232 uint32_t data_offset = 0; 233 234 if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID || 235 msg_id >= MOD_HDCP_MESSAGE_ID_MAX) 236 return MOD_HDCP_STATUS_DDC_FAILURE; 237 238 if (is_dp_hdcp(hdcp)) { 239 int num_dpcd_addrs = sizeof(hdcp_dpcd_addrs) / 240 sizeof(hdcp_dpcd_addrs[0]); 241 if (msg_id >= num_dpcd_addrs) 242 return MOD_HDCP_STATUS_DDC_FAILURE; 243 244 while (buf_len > 0) { 245 cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE); 246 success = hdcp->config.ddc.funcs.write_dpcd( 247 hdcp->config.ddc.handle, 248 hdcp_dpcd_addrs[msg_id] + data_offset, 249 buf + data_offset, 250 cur_size); 251 252 if (!success) 253 break; 254 255 buf_len -= cur_size; 256 data_offset += cur_size; 257 } 258 } else { 259 int num_i2c_offsets = sizeof(hdcp_i2c_offsets) / 260 sizeof(hdcp_i2c_offsets[0]); 261 if (msg_id >= num_i2c_offsets) 262 return MOD_HDCP_STATUS_DDC_FAILURE; 263 264 hdcp->buf[0] = hdcp_i2c_offsets[msg_id]; 265 memmove(&hdcp->buf[1], buf, buf_len); 266 success = hdcp->config.ddc.funcs.write_i2c( 267 hdcp->config.ddc.handle, 268 HDCP_I2C_ADDR, 269 hdcp->buf, 270 (uint32_t)(buf_len+1)); 271 } 272 273 return success ? MOD_HDCP_STATUS_SUCCESS : MOD_HDCP_STATUS_DDC_FAILURE; 274 } 275 276 enum mod_hdcp_status mod_hdcp_read_bksv(struct mod_hdcp *hdcp) 277 { 278 return read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BKSV, 279 hdcp->auth.msg.hdcp1.bksv, 280 sizeof(hdcp->auth.msg.hdcp1.bksv)); 281 } 282 283 enum mod_hdcp_status mod_hdcp_read_bcaps(struct mod_hdcp *hdcp) 284 { 285 return read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BCAPS, 286 &hdcp->auth.msg.hdcp1.bcaps, 287 sizeof(hdcp->auth.msg.hdcp1.bcaps)); 288 } 289 290 enum mod_hdcp_status mod_hdcp_read_bstatus(struct mod_hdcp *hdcp) 291 { 292 enum mod_hdcp_status status; 293 294 if (is_dp_hdcp(hdcp)) 295 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BSTATUS, 296 (uint8_t *)&hdcp->auth.msg.hdcp1.bstatus, 297 1); 298 else 299 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BSTATUS, 300 (uint8_t *)&hdcp->auth.msg.hdcp1.bstatus, 301 sizeof(hdcp->auth.msg.hdcp1.bstatus)); 302 return status; 303 } 304 305 enum mod_hdcp_status mod_hdcp_read_r0p(struct mod_hdcp *hdcp) 306 { 307 return read(hdcp, MOD_HDCP_MESSAGE_ID_READ_RI_R0, 308 (uint8_t *)&hdcp->auth.msg.hdcp1.r0p, 309 sizeof(hdcp->auth.msg.hdcp1.r0p)); 310 } 311 312 /* special case, reading repeatedly at the same address, don't use read() */ 313 enum mod_hdcp_status mod_hdcp_read_ksvlist(struct mod_hdcp *hdcp) 314 { 315 enum mod_hdcp_status status; 316 317 if (is_dp_hdcp(hdcp)) 318 status = read_repeatedly(hdcp, MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO, 319 hdcp->auth.msg.hdcp1.ksvlist, 320 hdcp->auth.msg.hdcp1.ksvlist_size, 321 KSV_READ_SIZE); 322 else 323 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO, 324 (uint8_t *)&hdcp->auth.msg.hdcp1.ksvlist, 325 hdcp->auth.msg.hdcp1.ksvlist_size); 326 return status; 327 } 328 329 enum mod_hdcp_status mod_hdcp_read_vp(struct mod_hdcp *hdcp) 330 { 331 enum mod_hdcp_status status; 332 333 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_0, 334 &hdcp->auth.msg.hdcp1.vp[0], 4); 335 if (status != MOD_HDCP_STATUS_SUCCESS) 336 goto out; 337 338 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_1, 339 &hdcp->auth.msg.hdcp1.vp[4], 4); 340 if (status != MOD_HDCP_STATUS_SUCCESS) 341 goto out; 342 343 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_2, 344 &hdcp->auth.msg.hdcp1.vp[8], 4); 345 if (status != MOD_HDCP_STATUS_SUCCESS) 346 goto out; 347 348 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_3, 349 &hdcp->auth.msg.hdcp1.vp[12], 4); 350 if (status != MOD_HDCP_STATUS_SUCCESS) 351 goto out; 352 353 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_4, 354 &hdcp->auth.msg.hdcp1.vp[16], 4); 355 out: 356 return status; 357 } 358 359 enum mod_hdcp_status mod_hdcp_read_binfo(struct mod_hdcp *hdcp) 360 { 361 enum mod_hdcp_status status; 362 363 if (is_dp_hdcp(hdcp)) 364 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BINFO, 365 (uint8_t *)&hdcp->auth.msg.hdcp1.binfo_dp, 366 sizeof(hdcp->auth.msg.hdcp1.binfo_dp)); 367 else 368 status = MOD_HDCP_STATUS_INVALID_OPERATION; 369 370 return status; 371 } 372 373 enum mod_hdcp_status mod_hdcp_write_aksv(struct mod_hdcp *hdcp) 374 { 375 return write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKSV, 376 hdcp->auth.msg.hdcp1.aksv, 377 sizeof(hdcp->auth.msg.hdcp1.aksv)); 378 } 379 380 enum mod_hdcp_status mod_hdcp_write_ainfo(struct mod_hdcp *hdcp) 381 { 382 return write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AINFO, 383 &hdcp->auth.msg.hdcp1.ainfo, 384 sizeof(hdcp->auth.msg.hdcp1.ainfo)); 385 } 386 387 enum mod_hdcp_status mod_hdcp_write_an(struct mod_hdcp *hdcp) 388 { 389 return write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AN, 390 hdcp->auth.msg.hdcp1.an, 391 sizeof(hdcp->auth.msg.hdcp1.an)); 392 } 393 394 enum mod_hdcp_status mod_hdcp_read_hdcp2version(struct mod_hdcp *hdcp) 395 { 396 enum mod_hdcp_status status; 397 398 if (is_dp_hdcp(hdcp)) 399 status = MOD_HDCP_STATUS_INVALID_OPERATION; 400 else 401 status = read(hdcp, MOD_HDCP_MESSAGE_ID_HDCP2VERSION, 402 &hdcp->auth.msg.hdcp2.hdcp2version_hdmi, 403 sizeof(hdcp->auth.msg.hdcp2.hdcp2version_hdmi)); 404 405 return status; 406 } 407 408 enum mod_hdcp_status mod_hdcp_read_rxcaps(struct mod_hdcp *hdcp) 409 { 410 enum mod_hdcp_status status; 411 412 if (!is_dp_hdcp(hdcp)) 413 status = MOD_HDCP_STATUS_INVALID_OPERATION; 414 else 415 status = read(hdcp, MOD_HDCP_MESSAGE_ID_RX_CAPS, 416 hdcp->auth.msg.hdcp2.rxcaps_dp, 417 sizeof(hdcp->auth.msg.hdcp2.rxcaps_dp)); 418 419 return status; 420 } 421 422 enum mod_hdcp_status mod_hdcp_read_rxstatus(struct mod_hdcp *hdcp) 423 { 424 enum mod_hdcp_status status; 425 426 if (is_dp_hdcp(hdcp)) { 427 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_RXSTATUS, 428 &hdcp->auth.msg.hdcp2.rxstatus_dp, 429 1); 430 } else { 431 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_RXSTATUS, 432 (uint8_t *)&hdcp->auth.msg.hdcp2.rxstatus, 433 sizeof(hdcp->auth.msg.hdcp2.rxstatus)); 434 } 435 return status; 436 } 437 438 enum mod_hdcp_status mod_hdcp_read_ake_cert(struct mod_hdcp *hdcp) 439 { 440 enum mod_hdcp_status status; 441 442 if (is_dp_hdcp(hdcp)) { 443 hdcp->auth.msg.hdcp2.ake_cert[0] = HDCP_2_2_AKE_SEND_CERT; 444 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT, 445 hdcp->auth.msg.hdcp2.ake_cert+1, 446 sizeof(hdcp->auth.msg.hdcp2.ake_cert)-1); 447 448 } else { 449 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT, 450 hdcp->auth.msg.hdcp2.ake_cert, 451 sizeof(hdcp->auth.msg.hdcp2.ake_cert)); 452 } 453 return status; 454 } 455 456 enum mod_hdcp_status mod_hdcp_read_h_prime(struct mod_hdcp *hdcp) 457 { 458 enum mod_hdcp_status status; 459 460 if (is_dp_hdcp(hdcp)) { 461 hdcp->auth.msg.hdcp2.ake_h_prime[0] = HDCP_2_2_AKE_SEND_HPRIME; 462 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME, 463 hdcp->auth.msg.hdcp2.ake_h_prime+1, 464 sizeof(hdcp->auth.msg.hdcp2.ake_h_prime)-1); 465 466 } else { 467 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME, 468 hdcp->auth.msg.hdcp2.ake_h_prime, 469 sizeof(hdcp->auth.msg.hdcp2.ake_h_prime)); 470 } 471 return status; 472 } 473 474 enum mod_hdcp_status mod_hdcp_read_pairing_info(struct mod_hdcp *hdcp) 475 { 476 enum mod_hdcp_status status; 477 478 if (is_dp_hdcp(hdcp)) { 479 hdcp->auth.msg.hdcp2.ake_pairing_info[0] = HDCP_2_2_AKE_SEND_PAIRING_INFO; 480 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO, 481 hdcp->auth.msg.hdcp2.ake_pairing_info+1, 482 sizeof(hdcp->auth.msg.hdcp2.ake_pairing_info)-1); 483 484 } else { 485 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO, 486 hdcp->auth.msg.hdcp2.ake_pairing_info, 487 sizeof(hdcp->auth.msg.hdcp2.ake_pairing_info)); 488 } 489 return status; 490 } 491 492 enum mod_hdcp_status mod_hdcp_read_l_prime(struct mod_hdcp *hdcp) 493 { 494 enum mod_hdcp_status status; 495 496 if (is_dp_hdcp(hdcp)) { 497 hdcp->auth.msg.hdcp2.lc_l_prime[0] = HDCP_2_2_LC_SEND_LPRIME; 498 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME, 499 hdcp->auth.msg.hdcp2.lc_l_prime+1, 500 sizeof(hdcp->auth.msg.hdcp2.lc_l_prime)-1); 501 502 } else { 503 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME, 504 hdcp->auth.msg.hdcp2.lc_l_prime, 505 sizeof(hdcp->auth.msg.hdcp2.lc_l_prime)); 506 } 507 return status; 508 } 509 510 enum mod_hdcp_status mod_hdcp_read_rx_id_list(struct mod_hdcp *hdcp) 511 { 512 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 513 514 if (is_dp_hdcp(hdcp)) { 515 uint32_t device_count = 0; 516 uint32_t rx_id_list_size = 0; 517 uint32_t bytes_read = 0; 518 519 hdcp->auth.msg.hdcp2.rx_id_list[0] = HDCP_2_2_REP_SEND_RECVID_LIST; 520 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST, 521 hdcp->auth.msg.hdcp2.rx_id_list+1, 522 HDCP_MAX_AUX_TRANSACTION_SIZE); 523 if (status == MOD_HDCP_STATUS_SUCCESS) { 524 bytes_read = HDCP_MAX_AUX_TRANSACTION_SIZE; 525 device_count = HDCP_2_2_DEV_COUNT_LO(hdcp->auth.msg.hdcp2.rx_id_list[2]) + 526 (HDCP_2_2_DEV_COUNT_HI(hdcp->auth.msg.hdcp2.rx_id_list[1]) << 4); 527 rx_id_list_size = MIN((21 + 5 * device_count), 528 (sizeof(hdcp->auth.msg.hdcp2.rx_id_list) - 1)); 529 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2, 530 hdcp->auth.msg.hdcp2.rx_id_list + 1 + bytes_read, 531 (rx_id_list_size - 1) / HDCP_MAX_AUX_TRANSACTION_SIZE * HDCP_MAX_AUX_TRANSACTION_SIZE); 532 } 533 } else { 534 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST, 535 hdcp->auth.msg.hdcp2.rx_id_list, 536 hdcp->auth.msg.hdcp2.rx_id_list_size); 537 } 538 return status; 539 } 540 541 enum mod_hdcp_status mod_hdcp_read_stream_ready(struct mod_hdcp *hdcp) 542 { 543 enum mod_hdcp_status status; 544 545 if (is_dp_hdcp(hdcp)) { 546 hdcp->auth.msg.hdcp2.repeater_auth_stream_ready[0] = HDCP_2_2_REP_STREAM_READY; 547 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY, 548 hdcp->auth.msg.hdcp2.repeater_auth_stream_ready+1, 549 sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready)-1); 550 551 } else { 552 status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY, 553 hdcp->auth.msg.hdcp2.repeater_auth_stream_ready, 554 sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready)); 555 } 556 return status; 557 } 558 559 enum mod_hdcp_status mod_hdcp_write_ake_init(struct mod_hdcp *hdcp) 560 { 561 enum mod_hdcp_status status; 562 563 if (is_dp_hdcp(hdcp)) 564 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT, 565 hdcp->auth.msg.hdcp2.ake_init+1, 566 sizeof(hdcp->auth.msg.hdcp2.ake_init)-1); 567 else 568 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT, 569 hdcp->auth.msg.hdcp2.ake_init, 570 sizeof(hdcp->auth.msg.hdcp2.ake_init)); 571 return status; 572 } 573 574 enum mod_hdcp_status mod_hdcp_write_no_stored_km(struct mod_hdcp *hdcp) 575 { 576 enum mod_hdcp_status status; 577 578 if (is_dp_hdcp(hdcp)) 579 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM, 580 hdcp->auth.msg.hdcp2.ake_no_stored_km+1, 581 sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km)-1); 582 else 583 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM, 584 hdcp->auth.msg.hdcp2.ake_no_stored_km, 585 sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km)); 586 return status; 587 } 588 589 enum mod_hdcp_status mod_hdcp_write_stored_km(struct mod_hdcp *hdcp) 590 { 591 enum mod_hdcp_status status; 592 593 if (is_dp_hdcp(hdcp)) 594 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM, 595 hdcp->auth.msg.hdcp2.ake_stored_km+1, 596 sizeof(hdcp->auth.msg.hdcp2.ake_stored_km)-1); 597 else 598 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM, 599 hdcp->auth.msg.hdcp2.ake_stored_km, 600 sizeof(hdcp->auth.msg.hdcp2.ake_stored_km)); 601 return status; 602 } 603 604 enum mod_hdcp_status mod_hdcp_write_lc_init(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_LC_INIT, 610 hdcp->auth.msg.hdcp2.lc_init+1, 611 sizeof(hdcp->auth.msg.hdcp2.lc_init)-1); 612 else 613 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT, 614 hdcp->auth.msg.hdcp2.lc_init, 615 sizeof(hdcp->auth.msg.hdcp2.lc_init)); 616 return status; 617 } 618 619 enum mod_hdcp_status mod_hdcp_write_eks(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_SKE_SEND_EKS, 626 hdcp->auth.msg.hdcp2.ske_eks+1, 627 sizeof(hdcp->auth.msg.hdcp2.ske_eks)-1); 628 else 629 status = write(hdcp, 630 MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS, 631 hdcp->auth.msg.hdcp2.ske_eks, 632 sizeof(hdcp->auth.msg.hdcp2.ske_eks)); 633 return status; 634 } 635 636 enum mod_hdcp_status mod_hdcp_write_repeater_auth_ack(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_REPEATER_AUTH_SEND_ACK, 642 hdcp->auth.msg.hdcp2.repeater_auth_ack+1, 643 sizeof(hdcp->auth.msg.hdcp2.repeater_auth_ack)-1); 644 else 645 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK, 646 hdcp->auth.msg.hdcp2.repeater_auth_ack, 647 sizeof(hdcp->auth.msg.hdcp2.repeater_auth_ack)); 648 return status; 649 } 650 651 enum mod_hdcp_status mod_hdcp_write_stream_manage(struct mod_hdcp *hdcp) 652 { 653 enum mod_hdcp_status status; 654 655 if (is_dp_hdcp(hdcp)) 656 status = write(hdcp, 657 MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE, 658 hdcp->auth.msg.hdcp2.repeater_auth_stream_manage+1, 659 hdcp->auth.msg.hdcp2.stream_manage_size-1); 660 else 661 status = write(hdcp, 662 MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE, 663 hdcp->auth.msg.hdcp2.repeater_auth_stream_manage, 664 hdcp->auth.msg.hdcp2.stream_manage_size); 665 return status; 666 } 667 668 enum mod_hdcp_status mod_hdcp_write_content_type(struct mod_hdcp *hdcp) 669 { 670 enum mod_hdcp_status status; 671 672 if (is_dp_hdcp(hdcp)) 673 status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE, 674 hdcp->auth.msg.hdcp2.content_stream_type_dp+1, 675 sizeof(hdcp->auth.msg.hdcp2.content_stream_type_dp)-1); 676 else 677 status = MOD_HDCP_STATUS_INVALID_OPERATION; 678 return status; 679 } 680 681 enum mod_hdcp_status mod_hdcp_clear_cp_irq_status(struct mod_hdcp *hdcp) 682 { 683 uint8_t clear_cp_irq_bit = DP_CP_IRQ; 684 uint32_t size = 1; 685 686 if (is_dp_hdcp(hdcp)) { 687 uint32_t cp_irq_addrs = (hdcp->connection.link.dp.rev >= 0x14) 688 ? DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0:DP_DEVICE_SERVICE_IRQ_VECTOR; 689 return hdcp->config.ddc.funcs.write_dpcd(hdcp->config.ddc.handle, cp_irq_addrs, 690 &clear_cp_irq_bit, size) ? MOD_HDCP_STATUS_SUCCESS : MOD_HDCP_STATUS_DDC_FAILURE; 691 } 692 693 return MOD_HDCP_STATUS_INVALID_OPERATION; 694 } 695