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