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