1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright 2023, Intel Corporation. 4 */ 5 6 #include <linux/err.h> 7 8 #include <drm/drm_print.h> 9 #include <drm/intel/i915_hdcp_interface.h> 10 11 #include "intel_display_core.h" 12 #include "intel_display_types.h" 13 #include "intel_hdcp_gsc.h" 14 #include "intel_hdcp_gsc_message.h" 15 16 static int 17 intel_hdcp_gsc_initiate_session(struct device *dev, struct hdcp_port_data *data, 18 struct hdcp2_ake_init *ake_data) 19 { 20 struct wired_cmd_initiate_hdcp2_session_in session_init_in = {}; 21 struct wired_cmd_initiate_hdcp2_session_out session_init_out = {}; 22 struct intel_hdcp_gsc_context *gsc_context; 23 struct intel_display *display; 24 ssize_t byte; 25 26 if (!dev || !data || !ake_data) 27 return -EINVAL; 28 29 display = to_intel_display(dev); 30 if (!display) { 31 dev_err(dev, "DRM not initialized, aborting HDCP.\n"); 32 return -ENODEV; 33 } 34 gsc_context = display->hdcp.gsc_context; 35 36 session_init_in.header.api_version = HDCP_API_VERSION; 37 session_init_in.header.command_id = WIRED_INITIATE_HDCP2_SESSION; 38 session_init_in.header.status = FW_HDCP_STATUS_SUCCESS; 39 session_init_in.header.buffer_len = 40 WIRED_CMD_BUF_LEN_INITIATE_HDCP2_SESSION_IN; 41 42 session_init_in.port.integrated_port_type = data->port_type; 43 session_init_in.port.physical_port = (u8)data->hdcp_ddi; 44 session_init_in.port.attached_transcoder = (u8)data->hdcp_transcoder; 45 session_init_in.protocol = data->protocol; 46 47 byte = intel_hdcp_gsc_msg_send(gsc_context, &session_init_in, 48 sizeof(session_init_in), 49 &session_init_out, 50 sizeof(session_init_out)); 51 if (byte < 0) { 52 drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); 53 return byte; 54 } 55 56 if (session_init_out.header.status != FW_HDCP_STATUS_SUCCESS) { 57 drm_dbg_kms(display->drm, "FW cmd 0x%08X Failed. Status: 0x%X\n", 58 WIRED_INITIATE_HDCP2_SESSION, 59 session_init_out.header.status); 60 return -EIO; 61 } 62 63 ake_data->msg_id = HDCP_2_2_AKE_INIT; 64 ake_data->tx_caps = session_init_out.tx_caps; 65 memcpy(ake_data->r_tx, session_init_out.r_tx, HDCP_2_2_RTX_LEN); 66 67 return 0; 68 } 69 70 static int 71 intel_hdcp_gsc_verify_receiver_cert_prepare_km(struct device *dev, 72 struct hdcp_port_data *data, 73 struct hdcp2_ake_send_cert *rx_cert, 74 bool *km_stored, 75 struct hdcp2_ake_no_stored_km 76 *ek_pub_km, 77 size_t *msg_sz) 78 { 79 struct wired_cmd_verify_receiver_cert_in verify_rxcert_in = {}; 80 struct wired_cmd_verify_receiver_cert_out verify_rxcert_out = {}; 81 struct intel_hdcp_gsc_context *gsc_context; 82 struct intel_display *display; 83 ssize_t byte; 84 85 if (!dev || !data || !rx_cert || !km_stored || !ek_pub_km || !msg_sz) 86 return -EINVAL; 87 88 display = to_intel_display(dev); 89 if (!display) { 90 dev_err(dev, "DRM not initialized, aborting HDCP.\n"); 91 return -ENODEV; 92 } 93 gsc_context = display->hdcp.gsc_context; 94 95 verify_rxcert_in.header.api_version = HDCP_API_VERSION; 96 verify_rxcert_in.header.command_id = WIRED_VERIFY_RECEIVER_CERT; 97 verify_rxcert_in.header.status = FW_HDCP_STATUS_SUCCESS; 98 verify_rxcert_in.header.buffer_len = 99 WIRED_CMD_BUF_LEN_VERIFY_RECEIVER_CERT_IN; 100 101 verify_rxcert_in.port.integrated_port_type = data->port_type; 102 verify_rxcert_in.port.physical_port = (u8)data->hdcp_ddi; 103 verify_rxcert_in.port.attached_transcoder = (u8)data->hdcp_transcoder; 104 105 verify_rxcert_in.cert_rx = rx_cert->cert_rx; 106 memcpy(verify_rxcert_in.r_rx, &rx_cert->r_rx, HDCP_2_2_RRX_LEN); 107 memcpy(verify_rxcert_in.rx_caps, rx_cert->rx_caps, HDCP_2_2_RXCAPS_LEN); 108 109 byte = intel_hdcp_gsc_msg_send(gsc_context, &verify_rxcert_in, 110 sizeof(verify_rxcert_in), 111 &verify_rxcert_out, 112 sizeof(verify_rxcert_out)); 113 if (byte < 0) { 114 drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed: %zd\n", byte); 115 return byte; 116 } 117 118 if (verify_rxcert_out.header.status != FW_HDCP_STATUS_SUCCESS) { 119 drm_dbg_kms(display->drm, "FW cmd 0x%08X Failed. Status: 0x%X\n", 120 WIRED_VERIFY_RECEIVER_CERT, 121 verify_rxcert_out.header.status); 122 return -EIO; 123 } 124 125 *km_stored = !!verify_rxcert_out.km_stored; 126 if (verify_rxcert_out.km_stored) { 127 ek_pub_km->msg_id = HDCP_2_2_AKE_STORED_KM; 128 *msg_sz = sizeof(struct hdcp2_ake_stored_km); 129 } else { 130 ek_pub_km->msg_id = HDCP_2_2_AKE_NO_STORED_KM; 131 *msg_sz = sizeof(struct hdcp2_ake_no_stored_km); 132 } 133 134 memcpy(ek_pub_km->e_kpub_km, &verify_rxcert_out.ekm_buff, 135 sizeof(verify_rxcert_out.ekm_buff)); 136 137 return 0; 138 } 139 140 static int 141 intel_hdcp_gsc_verify_hprime(struct device *dev, struct hdcp_port_data *data, 142 struct hdcp2_ake_send_hprime *rx_hprime) 143 { 144 struct wired_cmd_ake_send_hprime_in send_hprime_in = {}; 145 struct wired_cmd_ake_send_hprime_out send_hprime_out = {}; 146 struct intel_hdcp_gsc_context *gsc_context; 147 struct intel_display *display; 148 ssize_t byte; 149 150 if (!dev || !data || !rx_hprime) 151 return -EINVAL; 152 153 display = to_intel_display(dev); 154 if (!display) { 155 dev_err(dev, "DRM not initialized, aborting HDCP.\n"); 156 return -ENODEV; 157 } 158 gsc_context = display->hdcp.gsc_context; 159 160 send_hprime_in.header.api_version = HDCP_API_VERSION; 161 send_hprime_in.header.command_id = WIRED_AKE_SEND_HPRIME; 162 send_hprime_in.header.status = FW_HDCP_STATUS_SUCCESS; 163 send_hprime_in.header.buffer_len = WIRED_CMD_BUF_LEN_AKE_SEND_HPRIME_IN; 164 165 send_hprime_in.port.integrated_port_type = data->port_type; 166 send_hprime_in.port.physical_port = (u8)data->hdcp_ddi; 167 send_hprime_in.port.attached_transcoder = (u8)data->hdcp_transcoder; 168 169 memcpy(send_hprime_in.h_prime, rx_hprime->h_prime, 170 HDCP_2_2_H_PRIME_LEN); 171 172 byte = intel_hdcp_gsc_msg_send(gsc_context, &send_hprime_in, 173 sizeof(send_hprime_in), 174 &send_hprime_out, 175 sizeof(send_hprime_out)); 176 if (byte < 0) { 177 drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); 178 return byte; 179 } 180 181 if (send_hprime_out.header.status != FW_HDCP_STATUS_SUCCESS) { 182 drm_dbg_kms(display->drm, "FW cmd 0x%08X Failed. Status: 0x%X\n", 183 WIRED_AKE_SEND_HPRIME, send_hprime_out.header.status); 184 return -EIO; 185 } 186 187 return 0; 188 } 189 190 static int 191 intel_hdcp_gsc_store_pairing_info(struct device *dev, struct hdcp_port_data *data, 192 struct hdcp2_ake_send_pairing_info *pairing_info) 193 { 194 struct wired_cmd_ake_send_pairing_info_in pairing_info_in = {}; 195 struct wired_cmd_ake_send_pairing_info_out pairing_info_out = {}; 196 struct intel_hdcp_gsc_context *gsc_context; 197 struct intel_display *display; 198 ssize_t byte; 199 200 if (!dev || !data || !pairing_info) 201 return -EINVAL; 202 203 display = to_intel_display(dev); 204 if (!display) { 205 dev_err(dev, "DRM not initialized, aborting HDCP.\n"); 206 return -ENODEV; 207 } 208 gsc_context = display->hdcp.gsc_context; 209 210 pairing_info_in.header.api_version = HDCP_API_VERSION; 211 pairing_info_in.header.command_id = WIRED_AKE_SEND_PAIRING_INFO; 212 pairing_info_in.header.status = FW_HDCP_STATUS_SUCCESS; 213 pairing_info_in.header.buffer_len = 214 WIRED_CMD_BUF_LEN_SEND_PAIRING_INFO_IN; 215 216 pairing_info_in.port.integrated_port_type = data->port_type; 217 pairing_info_in.port.physical_port = (u8)data->hdcp_ddi; 218 pairing_info_in.port.attached_transcoder = (u8)data->hdcp_transcoder; 219 220 memcpy(pairing_info_in.e_kh_km, pairing_info->e_kh_km, 221 HDCP_2_2_E_KH_KM_LEN); 222 223 byte = intel_hdcp_gsc_msg_send(gsc_context, &pairing_info_in, 224 sizeof(pairing_info_in), 225 &pairing_info_out, 226 sizeof(pairing_info_out)); 227 if (byte < 0) { 228 drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); 229 return byte; 230 } 231 232 if (pairing_info_out.header.status != FW_HDCP_STATUS_SUCCESS) { 233 drm_dbg_kms(display->drm, "FW cmd 0x%08X failed. Status: 0x%X\n", 234 WIRED_AKE_SEND_PAIRING_INFO, 235 pairing_info_out.header.status); 236 return -EIO; 237 } 238 239 return 0; 240 } 241 242 static int 243 intel_hdcp_gsc_initiate_locality_check(struct device *dev, 244 struct hdcp_port_data *data, 245 struct hdcp2_lc_init *lc_init_data) 246 { 247 struct wired_cmd_init_locality_check_in lc_init_in = {}; 248 struct wired_cmd_init_locality_check_out lc_init_out = {}; 249 struct intel_hdcp_gsc_context *gsc_context; 250 struct intel_display *display; 251 ssize_t byte; 252 253 if (!dev || !data || !lc_init_data) 254 return -EINVAL; 255 256 display = to_intel_display(dev); 257 if (!display) { 258 dev_err(dev, "DRM not initialized, aborting HDCP.\n"); 259 return -ENODEV; 260 } 261 gsc_context = display->hdcp.gsc_context; 262 263 lc_init_in.header.api_version = HDCP_API_VERSION; 264 lc_init_in.header.command_id = WIRED_INIT_LOCALITY_CHECK; 265 lc_init_in.header.status = FW_HDCP_STATUS_SUCCESS; 266 lc_init_in.header.buffer_len = WIRED_CMD_BUF_LEN_INIT_LOCALITY_CHECK_IN; 267 268 lc_init_in.port.integrated_port_type = data->port_type; 269 lc_init_in.port.physical_port = (u8)data->hdcp_ddi; 270 lc_init_in.port.attached_transcoder = (u8)data->hdcp_transcoder; 271 272 byte = intel_hdcp_gsc_msg_send(gsc_context, &lc_init_in, sizeof(lc_init_in), 273 &lc_init_out, sizeof(lc_init_out)); 274 if (byte < 0) { 275 drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); 276 return byte; 277 } 278 279 if (lc_init_out.header.status != FW_HDCP_STATUS_SUCCESS) { 280 drm_dbg_kms(display->drm, "FW cmd 0x%08X Failed. status: 0x%X\n", 281 WIRED_INIT_LOCALITY_CHECK, lc_init_out.header.status); 282 return -EIO; 283 } 284 285 lc_init_data->msg_id = HDCP_2_2_LC_INIT; 286 memcpy(lc_init_data->r_n, lc_init_out.r_n, HDCP_2_2_RN_LEN); 287 288 return 0; 289 } 290 291 static int 292 intel_hdcp_gsc_verify_lprime(struct device *dev, struct hdcp_port_data *data, 293 struct hdcp2_lc_send_lprime *rx_lprime) 294 { 295 struct wired_cmd_validate_locality_in verify_lprime_in = {}; 296 struct wired_cmd_validate_locality_out verify_lprime_out = {}; 297 struct intel_hdcp_gsc_context *gsc_context; 298 struct intel_display *display; 299 ssize_t byte; 300 301 if (!dev || !data || !rx_lprime) 302 return -EINVAL; 303 304 display = to_intel_display(dev); 305 if (!display) { 306 dev_err(dev, "DRM not initialized, aborting HDCP.\n"); 307 return -ENODEV; 308 } 309 gsc_context = display->hdcp.gsc_context; 310 311 verify_lprime_in.header.api_version = HDCP_API_VERSION; 312 verify_lprime_in.header.command_id = WIRED_VALIDATE_LOCALITY; 313 verify_lprime_in.header.status = FW_HDCP_STATUS_SUCCESS; 314 verify_lprime_in.header.buffer_len = 315 WIRED_CMD_BUF_LEN_VALIDATE_LOCALITY_IN; 316 317 verify_lprime_in.port.integrated_port_type = data->port_type; 318 verify_lprime_in.port.physical_port = (u8)data->hdcp_ddi; 319 verify_lprime_in.port.attached_transcoder = (u8)data->hdcp_transcoder; 320 321 memcpy(verify_lprime_in.l_prime, rx_lprime->l_prime, 322 HDCP_2_2_L_PRIME_LEN); 323 324 byte = intel_hdcp_gsc_msg_send(gsc_context, &verify_lprime_in, 325 sizeof(verify_lprime_in), 326 &verify_lprime_out, 327 sizeof(verify_lprime_out)); 328 if (byte < 0) { 329 drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); 330 return byte; 331 } 332 333 if (verify_lprime_out.header.status != FW_HDCP_STATUS_SUCCESS) { 334 drm_dbg_kms(display->drm, "FW cmd 0x%08X failed. status: 0x%X\n", 335 WIRED_VALIDATE_LOCALITY, 336 verify_lprime_out.header.status); 337 return -EIO; 338 } 339 340 return 0; 341 } 342 343 static int 344 intel_hdcp_gsc_get_session_key(struct device *dev, 345 struct hdcp_port_data *data, 346 struct hdcp2_ske_send_eks *ske_data) 347 { 348 struct wired_cmd_get_session_key_in get_skey_in = {}; 349 struct wired_cmd_get_session_key_out get_skey_out = {}; 350 struct intel_hdcp_gsc_context *gsc_context; 351 struct intel_display *display; 352 ssize_t byte; 353 354 if (!dev || !data || !ske_data) 355 return -EINVAL; 356 357 display = to_intel_display(dev); 358 if (!display) { 359 dev_err(dev, "DRM not initialized, aborting HDCP.\n"); 360 return -ENODEV; 361 } 362 gsc_context = display->hdcp.gsc_context; 363 364 get_skey_in.header.api_version = HDCP_API_VERSION; 365 get_skey_in.header.command_id = WIRED_GET_SESSION_KEY; 366 get_skey_in.header.status = FW_HDCP_STATUS_SUCCESS; 367 get_skey_in.header.buffer_len = WIRED_CMD_BUF_LEN_GET_SESSION_KEY_IN; 368 369 get_skey_in.port.integrated_port_type = data->port_type; 370 get_skey_in.port.physical_port = (u8)data->hdcp_ddi; 371 get_skey_in.port.attached_transcoder = (u8)data->hdcp_transcoder; 372 373 byte = intel_hdcp_gsc_msg_send(gsc_context, &get_skey_in, sizeof(get_skey_in), 374 &get_skey_out, sizeof(get_skey_out)); 375 if (byte < 0) { 376 drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); 377 return byte; 378 } 379 380 if (get_skey_out.header.status != FW_HDCP_STATUS_SUCCESS) { 381 drm_dbg_kms(display->drm, "FW cmd 0x%08X failed. status: 0x%X\n", 382 WIRED_GET_SESSION_KEY, get_skey_out.header.status); 383 return -EIO; 384 } 385 386 ske_data->msg_id = HDCP_2_2_SKE_SEND_EKS; 387 memcpy(ske_data->e_dkey_ks, get_skey_out.e_dkey_ks, 388 HDCP_2_2_E_DKEY_KS_LEN); 389 memcpy(ske_data->riv, get_skey_out.r_iv, HDCP_2_2_RIV_LEN); 390 391 return 0; 392 } 393 394 static int 395 intel_hdcp_gsc_repeater_check_flow_prepare_ack(struct device *dev, 396 struct hdcp_port_data *data, 397 struct hdcp2_rep_send_receiverid_list 398 *rep_topology, 399 struct hdcp2_rep_send_ack 400 *rep_send_ack) 401 { 402 struct wired_cmd_verify_repeater_in verify_repeater_in = {}; 403 struct wired_cmd_verify_repeater_out verify_repeater_out = {}; 404 struct intel_hdcp_gsc_context *gsc_context; 405 struct intel_display *display; 406 ssize_t byte; 407 408 if (!dev || !rep_topology || !rep_send_ack || !data) 409 return -EINVAL; 410 411 display = to_intel_display(dev); 412 if (!display) { 413 dev_err(dev, "DRM not initialized, aborting HDCP.\n"); 414 return -ENODEV; 415 } 416 gsc_context = display->hdcp.gsc_context; 417 418 verify_repeater_in.header.api_version = HDCP_API_VERSION; 419 verify_repeater_in.header.command_id = WIRED_VERIFY_REPEATER; 420 verify_repeater_in.header.status = FW_HDCP_STATUS_SUCCESS; 421 verify_repeater_in.header.buffer_len = 422 WIRED_CMD_BUF_LEN_VERIFY_REPEATER_IN; 423 424 verify_repeater_in.port.integrated_port_type = data->port_type; 425 verify_repeater_in.port.physical_port = (u8)data->hdcp_ddi; 426 verify_repeater_in.port.attached_transcoder = (u8)data->hdcp_transcoder; 427 428 memcpy(verify_repeater_in.rx_info, rep_topology->rx_info, 429 HDCP_2_2_RXINFO_LEN); 430 memcpy(verify_repeater_in.seq_num_v, rep_topology->seq_num_v, 431 HDCP_2_2_SEQ_NUM_LEN); 432 memcpy(verify_repeater_in.v_prime, rep_topology->v_prime, 433 HDCP_2_2_V_PRIME_HALF_LEN); 434 memcpy(verify_repeater_in.receiver_ids, rep_topology->receiver_ids, 435 HDCP_2_2_RECEIVER_IDS_MAX_LEN); 436 437 byte = intel_hdcp_gsc_msg_send(gsc_context, &verify_repeater_in, 438 sizeof(verify_repeater_in), 439 &verify_repeater_out, 440 sizeof(verify_repeater_out)); 441 if (byte < 0) { 442 drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); 443 return byte; 444 } 445 446 if (verify_repeater_out.header.status != FW_HDCP_STATUS_SUCCESS) { 447 drm_dbg_kms(display->drm, "FW cmd 0x%08X failed. status: 0x%X\n", 448 WIRED_VERIFY_REPEATER, 449 verify_repeater_out.header.status); 450 return -EIO; 451 } 452 453 memcpy(rep_send_ack->v, verify_repeater_out.v, 454 HDCP_2_2_V_PRIME_HALF_LEN); 455 rep_send_ack->msg_id = HDCP_2_2_REP_SEND_ACK; 456 457 return 0; 458 } 459 460 static int 461 intel_hdcp_gsc_verify_mprime(struct device *dev, 462 struct hdcp_port_data *data, 463 struct hdcp2_rep_stream_ready *stream_ready) 464 { 465 struct wired_cmd_repeater_auth_stream_req_in *verify_mprime_in; 466 struct wired_cmd_repeater_auth_stream_req_out verify_mprime_out = {}; 467 struct intel_hdcp_gsc_context *gsc_context; 468 struct intel_display *display; 469 ssize_t byte; 470 size_t cmd_size; 471 472 if (!dev || !stream_ready || !data) 473 return -EINVAL; 474 475 display = to_intel_display(dev); 476 if (!display) { 477 dev_err(dev, "DRM not initialized, aborting HDCP.\n"); 478 return -ENODEV; 479 } 480 gsc_context = display->hdcp.gsc_context; 481 482 cmd_size = struct_size(verify_mprime_in, streams, data->k); 483 if (cmd_size == SIZE_MAX) 484 return -EINVAL; 485 486 verify_mprime_in = kzalloc(cmd_size, GFP_KERNEL); 487 if (!verify_mprime_in) 488 return -ENOMEM; 489 490 verify_mprime_in->header.api_version = HDCP_API_VERSION; 491 verify_mprime_in->header.command_id = WIRED_REPEATER_AUTH_STREAM_REQ; 492 verify_mprime_in->header.status = FW_HDCP_STATUS_SUCCESS; 493 verify_mprime_in->header.buffer_len = cmd_size - sizeof(verify_mprime_in->header); 494 495 verify_mprime_in->port.integrated_port_type = data->port_type; 496 verify_mprime_in->port.physical_port = (u8)data->hdcp_ddi; 497 verify_mprime_in->port.attached_transcoder = (u8)data->hdcp_transcoder; 498 499 memcpy(verify_mprime_in->m_prime, stream_ready->m_prime, HDCP_2_2_MPRIME_LEN); 500 drm_hdcp_cpu_to_be24(verify_mprime_in->seq_num_m, data->seq_num_m); 501 502 memcpy(verify_mprime_in->streams, data->streams, 503 array_size(data->k, sizeof(*data->streams))); 504 505 verify_mprime_in->k = cpu_to_be16(data->k); 506 507 byte = intel_hdcp_gsc_msg_send(gsc_context, verify_mprime_in, cmd_size, 508 &verify_mprime_out, 509 sizeof(verify_mprime_out)); 510 kfree(verify_mprime_in); 511 if (byte < 0) { 512 drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); 513 return byte; 514 } 515 516 if (verify_mprime_out.header.status != FW_HDCP_STATUS_SUCCESS) { 517 drm_dbg_kms(display->drm, "FW cmd 0x%08X failed. status: 0x%X\n", 518 WIRED_REPEATER_AUTH_STREAM_REQ, 519 verify_mprime_out.header.status); 520 return -EIO; 521 } 522 523 return 0; 524 } 525 526 static int intel_hdcp_gsc_enable_authentication(struct device *dev, 527 struct hdcp_port_data *data) 528 { 529 struct wired_cmd_enable_auth_in enable_auth_in = {}; 530 struct wired_cmd_enable_auth_out enable_auth_out = {}; 531 struct intel_hdcp_gsc_context *gsc_context; 532 struct intel_display *display; 533 ssize_t byte; 534 535 if (!dev || !data) 536 return -EINVAL; 537 538 display = to_intel_display(dev); 539 if (!display) { 540 dev_err(dev, "DRM not initialized, aborting HDCP.\n"); 541 return -ENODEV; 542 } 543 gsc_context = display->hdcp.gsc_context; 544 545 enable_auth_in.header.api_version = HDCP_API_VERSION; 546 enable_auth_in.header.command_id = WIRED_ENABLE_AUTH; 547 enable_auth_in.header.status = FW_HDCP_STATUS_SUCCESS; 548 enable_auth_in.header.buffer_len = WIRED_CMD_BUF_LEN_ENABLE_AUTH_IN; 549 550 enable_auth_in.port.integrated_port_type = data->port_type; 551 enable_auth_in.port.physical_port = (u8)data->hdcp_ddi; 552 enable_auth_in.port.attached_transcoder = (u8)data->hdcp_transcoder; 553 enable_auth_in.stream_type = data->streams[0].stream_type; 554 555 byte = intel_hdcp_gsc_msg_send(gsc_context, &enable_auth_in, 556 sizeof(enable_auth_in), 557 &enable_auth_out, 558 sizeof(enable_auth_out)); 559 if (byte < 0) { 560 drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); 561 return byte; 562 } 563 564 if (enable_auth_out.header.status != FW_HDCP_STATUS_SUCCESS) { 565 drm_dbg_kms(display->drm, "FW cmd 0x%08X failed. status: 0x%X\n", 566 WIRED_ENABLE_AUTH, enable_auth_out.header.status); 567 return -EIO; 568 } 569 570 return 0; 571 } 572 573 static int 574 intel_hdcp_gsc_close_session(struct device *dev, struct hdcp_port_data *data) 575 { 576 struct wired_cmd_close_session_in session_close_in = {}; 577 struct wired_cmd_close_session_out session_close_out = {}; 578 struct intel_hdcp_gsc_context *gsc_context; 579 struct intel_display *display; 580 ssize_t byte; 581 582 if (!dev || !data) 583 return -EINVAL; 584 585 display = to_intel_display(dev); 586 if (!display) { 587 dev_err(dev, "DRM not initialized, aborting HDCP.\n"); 588 return -ENODEV; 589 } 590 gsc_context = display->hdcp.gsc_context; 591 592 session_close_in.header.api_version = HDCP_API_VERSION; 593 session_close_in.header.command_id = WIRED_CLOSE_SESSION; 594 session_close_in.header.status = FW_HDCP_STATUS_SUCCESS; 595 session_close_in.header.buffer_len = 596 WIRED_CMD_BUF_LEN_CLOSE_SESSION_IN; 597 598 session_close_in.port.integrated_port_type = data->port_type; 599 session_close_in.port.physical_port = (u8)data->hdcp_ddi; 600 session_close_in.port.attached_transcoder = (u8)data->hdcp_transcoder; 601 602 byte = intel_hdcp_gsc_msg_send(gsc_context, &session_close_in, 603 sizeof(session_close_in), 604 &session_close_out, 605 sizeof(session_close_out)); 606 if (byte < 0) { 607 drm_dbg_kms(display->drm, "intel_hdcp_gsc_msg_send failed. %zd\n", byte); 608 return byte; 609 } 610 611 if (session_close_out.header.status != FW_HDCP_STATUS_SUCCESS) { 612 drm_dbg_kms(display->drm, "Session Close Failed. status: 0x%X\n", 613 session_close_out.header.status); 614 return -EIO; 615 } 616 617 return 0; 618 } 619 620 static const struct i915_hdcp_ops gsc_hdcp_ops = { 621 .initiate_hdcp2_session = intel_hdcp_gsc_initiate_session, 622 .verify_receiver_cert_prepare_km = 623 intel_hdcp_gsc_verify_receiver_cert_prepare_km, 624 .verify_hprime = intel_hdcp_gsc_verify_hprime, 625 .store_pairing_info = intel_hdcp_gsc_store_pairing_info, 626 .initiate_locality_check = intel_hdcp_gsc_initiate_locality_check, 627 .verify_lprime = intel_hdcp_gsc_verify_lprime, 628 .get_session_key = intel_hdcp_gsc_get_session_key, 629 .repeater_check_flow_prepare_ack = 630 intel_hdcp_gsc_repeater_check_flow_prepare_ack, 631 .verify_mprime = intel_hdcp_gsc_verify_mprime, 632 .enable_hdcp_authentication = intel_hdcp_gsc_enable_authentication, 633 .close_hdcp_session = intel_hdcp_gsc_close_session, 634 }; 635 636 int intel_hdcp_gsc_init(struct intel_display *display) 637 { 638 struct intel_hdcp_gsc_context *gsc_context; 639 struct i915_hdcp_arbiter *arbiter; 640 int ret = 0; 641 642 arbiter = kzalloc(sizeof(*arbiter), GFP_KERNEL); 643 if (!arbiter) 644 return -ENOMEM; 645 646 mutex_lock(&display->hdcp.hdcp_mutex); 647 648 gsc_context = intel_hdcp_gsc_context_alloc(display->drm); 649 if (IS_ERR(gsc_context)) { 650 ret = PTR_ERR(gsc_context); 651 kfree(arbiter); 652 goto out; 653 } 654 655 display->hdcp.arbiter = arbiter; 656 display->hdcp.arbiter->hdcp_dev = display->drm->dev; 657 display->hdcp.arbiter->ops = &gsc_hdcp_ops; 658 display->hdcp.gsc_context = gsc_context; 659 660 out: 661 mutex_unlock(&display->hdcp.hdcp_mutex); 662 663 return ret; 664 } 665 666 void intel_hdcp_gsc_fini(struct intel_display *display) 667 { 668 intel_hdcp_gsc_context_free(display->hdcp.gsc_context); 669 display->hdcp.gsc_context = NULL; 670 kfree(display->hdcp.arbiter); 671 display->hdcp.arbiter = NULL; 672 } 673