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