1026 lines · c
1/*2 * Copyright 2018 Advanced Micro Devices, Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * 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 OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 * Authors: AMD23 *24 */25 26#define MAX_NUM_DISPLAYS 2427 28 29#include "hdcp.h"30 31#include "amdgpu.h"32#include "hdcp_psp.h"33 34static void hdcp2_message_init(struct mod_hdcp *hdcp,35 struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *in)36{37 in->session_handle = hdcp->auth.id;38 in->prepare.msg1_id = TA_HDCP_HDCP2_MSG_ID__NULL_MESSAGE;39 in->prepare.msg2_id = TA_HDCP_HDCP2_MSG_ID__NULL_MESSAGE;40 in->process.msg1_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__NULL_MESSAGE;41 in->process.msg1_desc.msg_size = 0;42 in->process.msg2_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__NULL_MESSAGE;43 in->process.msg2_desc.msg_size = 0;44 in->process.msg3_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__NULL_MESSAGE;45 in->process.msg3_desc.msg_size = 0;46}47 48static enum mod_hdcp_status remove_display_from_topology_v2(49 struct mod_hdcp *hdcp, uint8_t index)50{51 struct psp_context *psp = hdcp->config.psp.handle;52 struct ta_dtm_shared_memory *dtm_cmd;53 struct mod_hdcp_display *display =54 get_active_display_at_index(hdcp, index);55 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;56 57 dtm_cmd = (struct ta_dtm_shared_memory *)psp->dtm_context.context.mem_context.shared_buf;58 59 if (!display || !is_display_active(display))60 return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND;61 62 mutex_lock(&psp->dtm_context.mutex);63 64 memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory));65 66 dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_UPDATE_V2;67 dtm_cmd->dtm_in_message.topology_update_v2.display_handle = display->index;68 dtm_cmd->dtm_in_message.topology_update_v2.is_active = 0;69 dtm_cmd->dtm_status = TA_DTM_STATUS__GENERIC_FAILURE;70 71 psp_dtm_invoke(psp, dtm_cmd->cmd_id);72 73 if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) {74 status = MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE;75 } else {76 display->state = MOD_HDCP_DISPLAY_ACTIVE;77 HDCP_TOP_REMOVE_DISPLAY_TRACE(hdcp, display->index);78 }79 80 mutex_unlock(&psp->dtm_context.mutex);81 return status;82}83 84static enum mod_hdcp_status remove_display_from_topology_v3(85 struct mod_hdcp *hdcp, uint8_t index)86{87 struct psp_context *psp = hdcp->config.psp.handle;88 struct ta_dtm_shared_memory *dtm_cmd;89 struct mod_hdcp_display *display =90 get_active_display_at_index(hdcp, index);91 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;92 93 dtm_cmd = (struct ta_dtm_shared_memory *)psp->dtm_context.context.mem_context.shared_buf;94 95 if (!display || !is_display_active(display))96 return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND;97 98 mutex_lock(&psp->dtm_context.mutex);99 100 memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory));101 102 dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_UPDATE_V3;103 dtm_cmd->dtm_in_message.topology_update_v3.display_handle = display->index;104 dtm_cmd->dtm_in_message.topology_update_v3.is_active = 0;105 dtm_cmd->dtm_status = TA_DTM_STATUS__GENERIC_FAILURE;106 107 psp_dtm_invoke(psp, dtm_cmd->cmd_id);108 mutex_unlock(&psp->dtm_context.mutex);109 110 if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) {111 status = remove_display_from_topology_v2(hdcp, index);112 if (status != MOD_HDCP_STATUS_SUCCESS)113 display->state = MOD_HDCP_DISPLAY_INACTIVE;114 } else {115 display->state = MOD_HDCP_DISPLAY_ACTIVE;116 HDCP_TOP_REMOVE_DISPLAY_TRACE(hdcp, display->index);117 }118 119 return status;120}121 122static enum mod_hdcp_status add_display_to_topology_v2(123 struct mod_hdcp *hdcp, struct mod_hdcp_display *display)124{125 struct psp_context *psp = hdcp->config.psp.handle;126 struct ta_dtm_shared_memory *dtm_cmd;127 struct mod_hdcp_link *link = &hdcp->connection.link;128 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;129 130 if (!psp->dtm_context.context.initialized) {131 DRM_INFO("Failed to add display topology, DTM TA is not initialized.");132 display->state = MOD_HDCP_DISPLAY_INACTIVE;133 return MOD_HDCP_STATUS_FAILURE;134 }135 136 dtm_cmd = (struct ta_dtm_shared_memory *)psp->dtm_context.context.mem_context.shared_buf;137 138 mutex_lock(&psp->dtm_context.mutex);139 memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory));140 141 dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_UPDATE_V2;142 dtm_cmd->dtm_in_message.topology_update_v2.display_handle = display->index;143 dtm_cmd->dtm_in_message.topology_update_v2.is_active = 1;144 dtm_cmd->dtm_in_message.topology_update_v2.controller = display->controller;145 dtm_cmd->dtm_in_message.topology_update_v2.ddc_line = link->ddc_line;146 dtm_cmd->dtm_in_message.topology_update_v2.dig_be = link->dig_be;147 dtm_cmd->dtm_in_message.topology_update_v2.dig_fe = display->dig_fe;148 if (is_dp_hdcp(hdcp))149 dtm_cmd->dtm_in_message.topology_update_v2.is_assr = link->dp.assr_enabled;150 151 dtm_cmd->dtm_in_message.topology_update_v2.dp_mst_vcid = display->vc_id;152 dtm_cmd->dtm_in_message.topology_update_v2.max_hdcp_supported_version =153 TA_DTM_HDCP_VERSION_MAX_SUPPORTED__2_2;154 dtm_cmd->dtm_status = TA_DTM_STATUS__GENERIC_FAILURE;155 156 psp_dtm_invoke(psp, dtm_cmd->cmd_id);157 158 if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) {159 display->state = MOD_HDCP_DISPLAY_INACTIVE;160 status = MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE;161 } else {162 HDCP_TOP_ADD_DISPLAY_TRACE(hdcp, display->index);163 }164 165 mutex_unlock(&psp->dtm_context.mutex);166 return status;167}168 169static enum mod_hdcp_status add_display_to_topology_v3(170 struct mod_hdcp *hdcp, struct mod_hdcp_display *display)171{172 struct psp_context *psp = hdcp->config.psp.handle;173 struct ta_dtm_shared_memory *dtm_cmd;174 struct mod_hdcp_link *link = &hdcp->connection.link;175 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;176 177 if (!psp->dtm_context.context.initialized) {178 DRM_INFO("Failed to add display topology, DTM TA is not initialized.");179 display->state = MOD_HDCP_DISPLAY_INACTIVE;180 return MOD_HDCP_STATUS_FAILURE;181 }182 183 dtm_cmd = (struct ta_dtm_shared_memory *)psp->dtm_context.context.mem_context.shared_buf;184 185 mutex_lock(&psp->dtm_context.mutex);186 memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory));187 188 dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_UPDATE_V3;189 dtm_cmd->dtm_in_message.topology_update_v3.display_handle = display->index;190 dtm_cmd->dtm_in_message.topology_update_v3.is_active = 1;191 dtm_cmd->dtm_in_message.topology_update_v3.controller = display->controller;192 dtm_cmd->dtm_in_message.topology_update_v3.ddc_line = link->ddc_line;193 dtm_cmd->dtm_in_message.topology_update_v3.link_enc = link->link_enc_idx;194 dtm_cmd->dtm_in_message.topology_update_v3.stream_enc = display->stream_enc_idx;195 if (is_dp_hdcp(hdcp))196 dtm_cmd->dtm_in_message.topology_update_v3.is_assr = link->dp.assr_enabled;197 198 dtm_cmd->dtm_in_message.topology_update_v3.dp_mst_vcid = display->vc_id;199 dtm_cmd->dtm_in_message.topology_update_v3.max_hdcp_supported_version =200 TA_DTM_HDCP_VERSION_MAX_SUPPORTED__2_3;201 dtm_cmd->dtm_in_message.topology_update_v3.encoder_type = TA_DTM_ENCODER_TYPE__DIG;202 dtm_cmd->dtm_status = TA_DTM_STATUS__GENERIC_FAILURE;203 dtm_cmd->dtm_in_message.topology_update_v3.phy_id = link->phy_idx;204 dtm_cmd->dtm_in_message.topology_update_v3.link_hdcp_cap = link->hdcp_supported_informational;205 dtm_cmd->dtm_in_message.topology_update_v3.dio_output_type = link->dp.usb4_enabled ?206 TA_DTM_DIO_OUTPUT_TYPE__DPIA :207 TA_DTM_DIO_OUTPUT_TYPE__DIRECT;208 dtm_cmd->dtm_in_message.topology_update_v3.dio_output_id = link->dio_output_id;209 210 psp_dtm_invoke(psp, dtm_cmd->cmd_id);211 mutex_unlock(&psp->dtm_context.mutex);212 213 if (dtm_cmd->dtm_status != TA_DTM_STATUS__SUCCESS) {214 status = add_display_to_topology_v2(hdcp, display);215 if (status != MOD_HDCP_STATUS_SUCCESS)216 display->state = MOD_HDCP_DISPLAY_INACTIVE;217 } else {218 HDCP_TOP_ADD_DISPLAY_TRACE(hdcp, display->index);219 }220 221 return status;222}223 224enum mod_hdcp_status mod_hdcp_remove_display_from_topology(225 struct mod_hdcp *hdcp, uint8_t index)226{227 enum mod_hdcp_status status = MOD_HDCP_STATUS_UPDATE_TOPOLOGY_FAILURE;228 229 if (hdcp->config.psp.caps.dtm_v3_supported)230 status = remove_display_from_topology_v3(hdcp, index);231 else232 status = remove_display_from_topology_v2(hdcp, index);233 234 return status;235}236 237enum mod_hdcp_status mod_hdcp_add_display_to_topology(struct mod_hdcp *hdcp,238 struct mod_hdcp_display *display)239{240 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;241 242 if (hdcp->config.psp.caps.dtm_v3_supported)243 status = add_display_to_topology_v3(hdcp, display);244 else245 status = add_display_to_topology_v2(hdcp, display);246 247 return status;248}249 250enum mod_hdcp_status mod_hdcp_hdcp1_create_session(struct mod_hdcp *hdcp)251{252 253 struct psp_context *psp = hdcp->config.psp.handle;254 struct mod_hdcp_display *display = get_first_active_display(hdcp);255 struct ta_hdcp_shared_memory *hdcp_cmd;256 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;257 258 if (!psp->hdcp_context.context.initialized) {259 DRM_ERROR("Failed to create hdcp session. HDCP TA is not initialized.");260 return MOD_HDCP_STATUS_FAILURE;261 }262 263 hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;264 265 mutex_lock(&psp->hdcp_context.mutex);266 memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));267 268 hdcp_cmd->in_msg.hdcp1_create_session.display_handle = display->index;269 hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP1_CREATE_SESSION;270 271 psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);272 273 hdcp->auth.id = hdcp_cmd->out_msg.hdcp1_create_session.session_handle;274 275 if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {276 status = MOD_HDCP_STATUS_HDCP1_CREATE_SESSION_FAILURE;277 } else {278 hdcp->auth.msg.hdcp1.ainfo = hdcp_cmd->out_msg.hdcp1_create_session.ainfo_primary;279 memcpy(hdcp->auth.msg.hdcp1.aksv, hdcp_cmd->out_msg.hdcp1_create_session.aksv_primary,280 sizeof(hdcp->auth.msg.hdcp1.aksv));281 memcpy(hdcp->auth.msg.hdcp1.an, hdcp_cmd->out_msg.hdcp1_create_session.an_primary,282 sizeof(hdcp->auth.msg.hdcp1.an));283 }284 285 mutex_unlock(&psp->hdcp_context.mutex);286 return status;287}288 289enum mod_hdcp_status mod_hdcp_hdcp1_destroy_session(struct mod_hdcp *hdcp)290{291 292 struct psp_context *psp = hdcp->config.psp.handle;293 struct ta_hdcp_shared_memory *hdcp_cmd;294 uint8_t i = 0;295 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;296 297 mutex_lock(&psp->hdcp_context.mutex);298 hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;299 memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));300 301 hdcp_cmd->in_msg.hdcp1_destroy_session.session_handle = hdcp->auth.id;302 hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP1_DESTROY_SESSION;303 304 psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);305 306 if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {307 status = MOD_HDCP_STATUS_HDCP1_DESTROY_SESSION_FAILURE;308 } else {309 HDCP_TOP_HDCP1_DESTROY_SESSION_TRACE(hdcp);310 for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++)311 if (is_display_encryption_enabled(&hdcp->displays[i])) {312 hdcp->displays[i].state =313 MOD_HDCP_DISPLAY_ACTIVE;314 HDCP_HDCP1_DISABLED_TRACE(315 hdcp, hdcp->displays[i].index);316 }317 }318 319 mutex_unlock(&psp->hdcp_context.mutex);320 return status;321}322 323enum mod_hdcp_status mod_hdcp_hdcp1_validate_rx(struct mod_hdcp *hdcp)324{325 struct psp_context *psp = hdcp->config.psp.handle;326 struct ta_hdcp_shared_memory *hdcp_cmd;327 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;328 329 mutex_lock(&psp->hdcp_context.mutex);330 hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;331 memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));332 333 hdcp_cmd->in_msg.hdcp1_first_part_authentication.session_handle = hdcp->auth.id;334 335 memcpy(hdcp_cmd->in_msg.hdcp1_first_part_authentication.bksv_primary, hdcp->auth.msg.hdcp1.bksv,336 TA_HDCP__HDCP1_KSV_SIZE);337 338 hdcp_cmd->in_msg.hdcp1_first_part_authentication.r0_prime_primary = hdcp->auth.msg.hdcp1.r0p;339 hdcp_cmd->in_msg.hdcp1_first_part_authentication.bcaps = hdcp->auth.msg.hdcp1.bcaps;340 hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP1_FIRST_PART_AUTHENTICATION;341 342 psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);343 344 if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {345 status = MOD_HDCP_STATUS_HDCP1_VALIDATE_RX_FAILURE;346 } else if (hdcp_cmd->out_msg.hdcp1_first_part_authentication.authentication_status ==347 TA_HDCP_AUTHENTICATION_STATUS__HDCP1_FIRST_PART_COMPLETE) {348 /* needs second part of authentication */349 hdcp->connection.is_repeater = 1;350 } else if (hdcp_cmd->out_msg.hdcp1_first_part_authentication.authentication_status ==351 TA_HDCP_AUTHENTICATION_STATUS__HDCP1_AUTHENTICATED) {352 hdcp->connection.is_repeater = 0;353 } else if (hdcp_cmd->out_msg.hdcp1_first_part_authentication.authentication_status ==354 TA_HDCP_AUTHENTICATION_STATUS__HDCP1_KSV_REVOKED) {355 hdcp->connection.is_hdcp1_revoked = 1;356 status = MOD_HDCP_STATUS_HDCP1_BKSV_REVOKED;357 } else358 status = MOD_HDCP_STATUS_HDCP1_VALIDATE_RX_FAILURE;359 360 mutex_unlock(&psp->hdcp_context.mutex);361 return status;362}363 364enum mod_hdcp_status mod_hdcp_hdcp1_enable_encryption(struct mod_hdcp *hdcp)365{366 struct psp_context *psp = hdcp->config.psp.handle;367 struct ta_hdcp_shared_memory *hdcp_cmd;368 struct mod_hdcp_display *display = get_first_active_display(hdcp);369 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;370 371 mutex_lock(&psp->hdcp_context.mutex);372 hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;373 memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));374 375 hdcp_cmd->in_msg.hdcp1_enable_encryption.session_handle = hdcp->auth.id;376 hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP1_ENABLE_ENCRYPTION;377 378 psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);379 380 if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {381 status = MOD_HDCP_STATUS_HDCP1_ENABLE_ENCRYPTION_FAILURE;382 } else if (!is_dp_mst_hdcp(hdcp)) {383 display->state = MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED;384 HDCP_HDCP1_ENABLED_TRACE(hdcp, display->index);385 }386 387 mutex_unlock(&psp->hdcp_context.mutex);388 return status;389}390 391enum mod_hdcp_status mod_hdcp_hdcp1_validate_ksvlist_vp(struct mod_hdcp *hdcp)392{393 struct psp_context *psp = hdcp->config.psp.handle;394 struct ta_hdcp_shared_memory *hdcp_cmd;395 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;396 397 mutex_lock(&psp->hdcp_context.mutex);398 hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;399 memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));400 401 hdcp_cmd->in_msg.hdcp1_second_part_authentication.session_handle = hdcp->auth.id;402 403 hdcp_cmd->in_msg.hdcp1_second_part_authentication.ksv_list_size = hdcp->auth.msg.hdcp1.ksvlist_size;404 memcpy(hdcp_cmd->in_msg.hdcp1_second_part_authentication.ksv_list, hdcp->auth.msg.hdcp1.ksvlist,405 hdcp->auth.msg.hdcp1.ksvlist_size);406 407 memcpy(hdcp_cmd->in_msg.hdcp1_second_part_authentication.v_prime, hdcp->auth.msg.hdcp1.vp,408 sizeof(hdcp->auth.msg.hdcp1.vp));409 410 hdcp_cmd->in_msg.hdcp1_second_part_authentication.bstatus_binfo =411 is_dp_hdcp(hdcp) ? hdcp->auth.msg.hdcp1.binfo_dp : hdcp->auth.msg.hdcp1.bstatus;412 hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP1_SECOND_PART_AUTHENTICATION;413 414 psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);415 416 if (hdcp_cmd->hdcp_status == TA_HDCP_STATUS__SUCCESS &&417 hdcp_cmd->out_msg.hdcp1_second_part_authentication.authentication_status ==418 TA_HDCP_AUTHENTICATION_STATUS__HDCP1_AUTHENTICATED) {419 status = MOD_HDCP_STATUS_SUCCESS;420 } else if (hdcp_cmd->out_msg.hdcp1_second_part_authentication.authentication_status ==421 TA_HDCP_AUTHENTICATION_STATUS__HDCP1_KSV_REVOKED) {422 hdcp->connection.is_hdcp1_revoked = 1;423 status = MOD_HDCP_STATUS_HDCP1_KSV_LIST_REVOKED;424 } else {425 status = MOD_HDCP_STATUS_HDCP1_VALIDATE_KSV_LIST_FAILURE;426 }427 428 mutex_unlock(&psp->hdcp_context.mutex);429 return status;430}431 432enum mod_hdcp_status mod_hdcp_hdcp1_enable_dp_stream_encryption(struct mod_hdcp *hdcp)433{434 435 struct psp_context *psp = hdcp->config.psp.handle;436 struct ta_hdcp_shared_memory *hdcp_cmd;437 int i = 0;438 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;439 440 mutex_lock(&psp->hdcp_context.mutex);441 hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;442 443 for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) {444 445 if (hdcp->displays[i].adjust.disable || hdcp->displays[i].state != MOD_HDCP_DISPLAY_ACTIVE)446 continue;447 448 memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));449 450 hdcp_cmd->in_msg.hdcp1_enable_dp_stream_encryption.session_handle = hdcp->auth.id;451 hdcp_cmd->in_msg.hdcp1_enable_dp_stream_encryption.display_handle = hdcp->displays[i].index;452 hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP1_ENABLE_DP_STREAM_ENCRYPTION;453 454 psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);455 456 if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {457 status = MOD_HDCP_STATUS_HDCP1_ENABLE_STREAM_ENCRYPTION_FAILURE;458 break;459 }460 461 hdcp->displays[i].state = MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED;462 HDCP_HDCP1_ENABLED_TRACE(hdcp, hdcp->displays[i].index);463 }464 465 mutex_unlock(&psp->hdcp_context.mutex);466 return status;467}468 469enum mod_hdcp_status mod_hdcp_hdcp1_link_maintenance(struct mod_hdcp *hdcp)470{471 struct psp_context *psp = hdcp->config.psp.handle;472 struct ta_hdcp_shared_memory *hdcp_cmd;473 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;474 475 mutex_lock(&psp->hdcp_context.mutex);476 hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;477 478 memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));479 480 hdcp_cmd->in_msg.hdcp1_get_encryption_status.session_handle = hdcp->auth.id;481 482 hdcp_cmd->out_msg.hdcp1_get_encryption_status.protection_level = 0;483 hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP1_GET_ENCRYPTION_STATUS;484 485 psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);486 487 if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS ||488 hdcp_cmd->out_msg.hdcp1_get_encryption_status.protection_level != 1)489 status = MOD_HDCP_STATUS_HDCP1_LINK_MAINTENANCE_FAILURE;490 491 mutex_unlock(&psp->hdcp_context.mutex);492 return status;493}494 495enum mod_hdcp_status mod_hdcp_hdcp2_create_session(struct mod_hdcp *hdcp)496{497 struct psp_context *psp = hdcp->config.psp.handle;498 struct ta_hdcp_shared_memory *hdcp_cmd;499 struct mod_hdcp_display *display = get_first_active_display(hdcp);500 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;501 502 503 if (!psp->hdcp_context.context.initialized) {504 DRM_ERROR("Failed to create hdcp session, HDCP TA is not initialized");505 return MOD_HDCP_STATUS_FAILURE;506 }507 508 if (!display)509 return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND;510 511 mutex_lock(&psp->hdcp_context.mutex);512 513 hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;514 memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));515 516 hdcp_cmd->in_msg.hdcp2_create_session_v2.display_handle = display->index;517 518 if (hdcp->connection.link.adjust.hdcp2.force_type == MOD_HDCP_FORCE_TYPE_0)519 hdcp_cmd->in_msg.hdcp2_create_session_v2.negotiate_content_type =520 TA_HDCP2_CONTENT_TYPE_NEGOTIATION_TYPE__FORCE_TYPE0;521 else if (hdcp->connection.link.adjust.hdcp2.force_type == MOD_HDCP_FORCE_TYPE_1)522 hdcp_cmd->in_msg.hdcp2_create_session_v2.negotiate_content_type =523 TA_HDCP2_CONTENT_TYPE_NEGOTIATION_TYPE__FORCE_TYPE1;524 else if (hdcp->connection.link.adjust.hdcp2.force_type == MOD_HDCP_FORCE_TYPE_MAX)525 hdcp_cmd->in_msg.hdcp2_create_session_v2.negotiate_content_type =526 TA_HDCP2_CONTENT_TYPE_NEGOTIATION_TYPE__MAX_SUPPORTED;527 528 hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_CREATE_SESSION_V2;529 530 psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);531 532 533 if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)534 status = MOD_HDCP_STATUS_HDCP2_CREATE_SESSION_FAILURE;535 else536 hdcp->auth.id = hdcp_cmd->out_msg.hdcp2_create_session_v2.session_handle;537 538 mutex_unlock(&psp->hdcp_context.mutex);539 return status;540}541 542enum mod_hdcp_status mod_hdcp_hdcp2_destroy_session(struct mod_hdcp *hdcp)543{544 struct psp_context *psp = hdcp->config.psp.handle;545 struct ta_hdcp_shared_memory *hdcp_cmd;546 uint8_t i = 0;547 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;548 549 mutex_lock(&psp->hdcp_context.mutex);550 hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;551 memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));552 553 hdcp_cmd->in_msg.hdcp2_destroy_session.session_handle = hdcp->auth.id;554 hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_DESTROY_SESSION;555 556 psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);557 558 if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {559 status = MOD_HDCP_STATUS_HDCP2_DESTROY_SESSION_FAILURE;560 } else {561 HDCP_TOP_HDCP2_DESTROY_SESSION_TRACE(hdcp);562 for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++)563 if (is_display_encryption_enabled(&hdcp->displays[i])) {564 hdcp->displays[i].state =565 MOD_HDCP_DISPLAY_ACTIVE;566 HDCP_HDCP2_DISABLED_TRACE(567 hdcp, hdcp->displays[i].index);568 }569 }570 571 mutex_unlock(&psp->hdcp_context.mutex);572 return status;573}574 575enum mod_hdcp_status mod_hdcp_hdcp2_prepare_ake_init(struct mod_hdcp *hdcp)576{577 struct psp_context *psp = hdcp->config.psp.handle;578 struct ta_hdcp_shared_memory *hdcp_cmd;579 struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;580 struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;581 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;582 583 mutex_lock(&psp->hdcp_context.mutex);584 hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;585 memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));586 587 msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2;588 msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2;589 590 hdcp2_message_init(hdcp, msg_in);591 592 hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2;593 msg_in->prepare.msg1_id = TA_HDCP_HDCP2_MSG_ID__AKE_INIT;594 595 psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);596 597 if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)598 status = MOD_HDCP_STATUS_HDCP2_PREP_AKE_INIT_FAILURE;599 else600 memcpy(&hdcp->auth.msg.hdcp2.ake_init[0], &msg_out->prepare.transmitter_message[0],601 sizeof(hdcp->auth.msg.hdcp2.ake_init));602 603 mutex_unlock(&psp->hdcp_context.mutex);604 return status;605}606 607enum mod_hdcp_status mod_hdcp_hdcp2_validate_ake_cert(struct mod_hdcp *hdcp)608{609 struct psp_context *psp = hdcp->config.psp.handle;610 struct ta_hdcp_shared_memory *hdcp_cmd;611 struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;612 struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;613 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;614 615 mutex_lock(&psp->hdcp_context.mutex);616 hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;617 memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));618 619 msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2;620 msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2;621 622 hdcp2_message_init(hdcp, msg_in);623 624 msg_in->process.msg1_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__AKE_SEND_CERT;625 msg_in->process.msg1_desc.msg_size = TA_HDCP_HDCP2_MSG_ID_MAX_SIZE__AKE_SEND_CERT;626 627 memcpy(&msg_in->process.receiver_message[0], hdcp->auth.msg.hdcp2.ake_cert,628 sizeof(hdcp->auth.msg.hdcp2.ake_cert));629 630 msg_in->prepare.msg1_id = TA_HDCP_HDCP2_MSG_ID__AKE_NO_STORED_KM;631 msg_in->prepare.msg2_id = TA_HDCP_HDCP2_MSG_ID__AKE_STORED_KM;632 633 hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2;634 635 psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);636 637 if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {638 status = MOD_HDCP_STATUS_HDCP2_VALIDATE_AKE_CERT_FAILURE;639 } else {640 memcpy(hdcp->auth.msg.hdcp2.ake_no_stored_km,641 &msg_out->prepare.transmitter_message[0],642 sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km));643 644 memcpy(hdcp->auth.msg.hdcp2.ake_stored_km,645 &msg_out->prepare.transmitter_message[sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km)],646 sizeof(hdcp->auth.msg.hdcp2.ake_stored_km));647 648 if (msg_out->process.msg1_status ==649 TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS) {650 hdcp->connection.is_km_stored =651 msg_out->process.is_km_stored ? 1 : 0;652 hdcp->connection.is_repeater =653 msg_out->process.is_repeater ? 1 : 0;654 status = MOD_HDCP_STATUS_SUCCESS;655 } else if (msg_out->process.msg1_status ==656 TA_HDCP2_MSG_AUTHENTICATION_STATUS__RECEIVERID_REVOKED) {657 hdcp->connection.is_hdcp2_revoked = 1;658 status = MOD_HDCP_STATUS_HDCP2_AKE_CERT_REVOKED;659 } else {660 status = MOD_HDCP_STATUS_HDCP2_VALIDATE_AKE_CERT_FAILURE;661 }662 }663 mutex_unlock(&psp->hdcp_context.mutex);664 return status;665}666 667enum mod_hdcp_status mod_hdcp_hdcp2_validate_h_prime(struct mod_hdcp *hdcp)668{669 struct psp_context *psp = hdcp->config.psp.handle;670 struct ta_hdcp_shared_memory *hdcp_cmd;671 struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;672 struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;673 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;674 675 mutex_lock(&psp->hdcp_context.mutex);676 hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;677 memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));678 679 msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2;680 msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2;681 682 hdcp2_message_init(hdcp, msg_in);683 684 msg_in->process.msg1_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__AKE_SEND_H_PRIME;685 msg_in->process.msg1_desc.msg_size = TA_HDCP_HDCP2_MSG_ID_MAX_SIZE__AKE_SEND_H_PRIME;686 687 memcpy(&msg_in->process.receiver_message[0], hdcp->auth.msg.hdcp2.ake_h_prime,688 sizeof(hdcp->auth.msg.hdcp2.ake_h_prime));689 690 if (!hdcp->connection.is_km_stored) {691 msg_in->process.msg2_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__AKE_SEND_PAIRING_INFO;692 msg_in->process.msg2_desc.msg_size = TA_HDCP_HDCP2_MSG_ID_MAX_SIZE__AKE_SEND_PAIRING_INFO;693 memcpy(&msg_in->process.receiver_message[sizeof(hdcp->auth.msg.hdcp2.ake_h_prime)],694 hdcp->auth.msg.hdcp2.ake_pairing_info, sizeof(hdcp->auth.msg.hdcp2.ake_pairing_info));695 }696 697 hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2;698 699 psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);700 701 if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)702 status = MOD_HDCP_STATUS_HDCP2_VALIDATE_H_PRIME_FAILURE;703 else if (msg_out->process.msg1_status != TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS)704 status = MOD_HDCP_STATUS_HDCP2_VALIDATE_H_PRIME_FAILURE;705 else if (!hdcp->connection.is_km_stored &&706 msg_out->process.msg2_status != TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS)707 status = MOD_HDCP_STATUS_HDCP2_VALIDATE_PAIRING_INFO_FAILURE;708 709 mutex_unlock(&psp->hdcp_context.mutex);710 return status;711}712 713enum mod_hdcp_status mod_hdcp_hdcp2_prepare_lc_init(struct mod_hdcp *hdcp)714{715 struct psp_context *psp = hdcp->config.psp.handle;716 struct ta_hdcp_shared_memory *hdcp_cmd;717 struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;718 struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;719 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;720 721 mutex_lock(&psp->hdcp_context.mutex);722 hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;723 memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));724 725 msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2;726 msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2;727 728 hdcp2_message_init(hdcp, msg_in);729 730 msg_in->prepare.msg1_id = TA_HDCP_HDCP2_MSG_ID__LC_INIT;731 732 hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2;733 734 psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);735 736 if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)737 status = MOD_HDCP_STATUS_HDCP2_PREP_LC_INIT_FAILURE;738 else739 memcpy(hdcp->auth.msg.hdcp2.lc_init, &msg_out->prepare.transmitter_message[0],740 sizeof(hdcp->auth.msg.hdcp2.lc_init));741 742 mutex_unlock(&psp->hdcp_context.mutex);743 return status;744}745 746enum mod_hdcp_status mod_hdcp_hdcp2_validate_l_prime(struct mod_hdcp *hdcp)747{748 struct psp_context *psp = hdcp->config.psp.handle;749 struct ta_hdcp_shared_memory *hdcp_cmd;750 struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;751 struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;752 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;753 754 mutex_lock(&psp->hdcp_context.mutex);755 hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;756 memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));757 758 msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2;759 msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2;760 761 hdcp2_message_init(hdcp, msg_in);762 763 msg_in->process.msg1_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__LC_SEND_L_PRIME;764 msg_in->process.msg1_desc.msg_size = TA_HDCP_HDCP2_MSG_ID_MAX_SIZE__LC_SEND_L_PRIME;765 766 memcpy(&msg_in->process.receiver_message[0], hdcp->auth.msg.hdcp2.lc_l_prime,767 sizeof(hdcp->auth.msg.hdcp2.lc_l_prime));768 769 hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2;770 771 psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);772 773 if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS ||774 msg_out->process.msg1_status != TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS)775 status = MOD_HDCP_STATUS_HDCP2_VALIDATE_L_PRIME_FAILURE;776 777 mutex_unlock(&psp->hdcp_context.mutex);778 return status;779}780 781enum mod_hdcp_status mod_hdcp_hdcp2_prepare_eks(struct mod_hdcp *hdcp)782{783 struct psp_context *psp = hdcp->config.psp.handle;784 struct ta_hdcp_shared_memory *hdcp_cmd;785 struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;786 struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;787 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;788 789 mutex_lock(&psp->hdcp_context.mutex);790 hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;791 memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));792 793 msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2;794 msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2;795 796 hdcp2_message_init(hdcp, msg_in);797 798 msg_in->prepare.msg1_id = TA_HDCP_HDCP2_MSG_ID__SKE_SEND_EKS;799 800 if (is_dp_hdcp(hdcp))801 msg_in->prepare.msg2_id = TA_HDCP_HDCP2_MSG_ID__SIGNAL_CONTENT_STREAM_TYPE_DP;802 803 hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2;804 psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);805 806 if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {807 status = MOD_HDCP_STATUS_HDCP2_PREP_EKS_FAILURE;808 } else {809 memcpy(hdcp->auth.msg.hdcp2.ske_eks,810 &msg_out->prepare.transmitter_message[0],811 sizeof(hdcp->auth.msg.hdcp2.ske_eks));812 msg_out->prepare.msg1_desc.msg_size =813 sizeof(hdcp->auth.msg.hdcp2.ske_eks);814 815 if (is_dp_hdcp(hdcp)) {816 memcpy(hdcp->auth.msg.hdcp2.content_stream_type_dp,817 &msg_out->prepare.transmitter_message[sizeof(hdcp->auth.msg.hdcp2.ske_eks)],818 sizeof(hdcp->auth.msg.hdcp2.content_stream_type_dp));819 }820 }821 mutex_unlock(&psp->hdcp_context.mutex);822 823 return status;824}825 826enum mod_hdcp_status mod_hdcp_hdcp2_enable_encryption(struct mod_hdcp *hdcp)827{828 struct psp_context *psp = hdcp->config.psp.handle;829 struct ta_hdcp_shared_memory *hdcp_cmd;830 struct mod_hdcp_display *display = get_first_active_display(hdcp);831 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;832 833 if (!display)834 return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND;835 836 mutex_lock(&psp->hdcp_context.mutex);837 838 hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;839 memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));840 841 hdcp_cmd->in_msg.hdcp2_set_encryption.session_handle = hdcp->auth.id;842 843 hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_SET_ENCRYPTION;844 psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);845 846 if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {847 status = MOD_HDCP_STATUS_HDCP2_ENABLE_ENCRYPTION_FAILURE;848 } else if (!is_dp_mst_hdcp(hdcp)) {849 display->state = MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED;850 HDCP_HDCP2_ENABLED_TRACE(hdcp, display->index);851 }852 853 mutex_unlock(&psp->hdcp_context.mutex);854 return status;855}856 857enum mod_hdcp_status mod_hdcp_hdcp2_validate_rx_id_list(struct mod_hdcp *hdcp)858{859 struct psp_context *psp = hdcp->config.psp.handle;860 struct ta_hdcp_shared_memory *hdcp_cmd;861 struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;862 struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;863 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;864 865 mutex_lock(&psp->hdcp_context.mutex);866 867 hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;868 memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));869 870 msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2;871 msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2;872 873 hdcp2_message_init(hdcp, msg_in);874 875 msg_in->process.msg1_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__REPEATERAUTH_SEND_RECEIVERID_LIST;876 msg_in->process.msg1_desc.msg_size = sizeof(hdcp->auth.msg.hdcp2.rx_id_list);877 memcpy(&msg_in->process.receiver_message[0], hdcp->auth.msg.hdcp2.rx_id_list,878 sizeof(hdcp->auth.msg.hdcp2.rx_id_list));879 880 msg_in->prepare.msg1_id = TA_HDCP_HDCP2_MSG_ID__REPEATERAUTH_SEND_ACK;881 882 hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2;883 884 psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);885 886 if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {887 status = MOD_HDCP_STATUS_HDCP2_VALIDATE_RX_ID_LIST_FAILURE;888 } else {889 memcpy(hdcp->auth.msg.hdcp2.repeater_auth_ack,890 &msg_out->prepare.transmitter_message[0],891 sizeof(hdcp->auth.msg.hdcp2.repeater_auth_ack));892 893 if (msg_out->process.msg1_status ==894 TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS) {895 hdcp->connection.is_km_stored = msg_out->process.is_km_stored ? 1 : 0;896 hdcp->connection.is_repeater = msg_out->process.is_repeater ? 1 : 0;897 status = MOD_HDCP_STATUS_SUCCESS;898 } else if (msg_out->process.msg1_status ==899 TA_HDCP2_MSG_AUTHENTICATION_STATUS__RECEIVERID_REVOKED) {900 hdcp->connection.is_hdcp2_revoked = 1;901 status = MOD_HDCP_STATUS_HDCP2_RX_ID_LIST_REVOKED;902 } else {903 status = MOD_HDCP_STATUS_HDCP2_VALIDATE_RX_ID_LIST_FAILURE;904 }905 }906 mutex_unlock(&psp->hdcp_context.mutex);907 return status;908}909 910enum mod_hdcp_status mod_hdcp_hdcp2_enable_dp_stream_encryption(struct mod_hdcp *hdcp)911{912 struct psp_context *psp = hdcp->config.psp.handle;913 struct ta_hdcp_shared_memory *hdcp_cmd;914 struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;915 uint8_t i;916 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;917 918 mutex_lock(&psp->hdcp_context.mutex);919 hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;920 memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));921 922 msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2;923 924 hdcp2_message_init(hdcp, msg_in);925 926 927 for (i = 0; i < MAX_NUM_OF_DISPLAYS; i++) {928 if (hdcp->displays[i].adjust.disable || hdcp->displays[i].state != MOD_HDCP_DISPLAY_ACTIVE)929 continue;930 931 hdcp_cmd->in_msg.hdcp2_enable_dp_stream_encryption.display_handle = hdcp->displays[i].index;932 hdcp_cmd->in_msg.hdcp2_enable_dp_stream_encryption.session_handle = hdcp->auth.id;933 934 hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_ENABLE_DP_STREAM_ENCRYPTION;935 psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);936 937 if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS)938 break;939 940 hdcp->displays[i].state = MOD_HDCP_DISPLAY_ENCRYPTION_ENABLED;941 HDCP_HDCP2_ENABLED_TRACE(hdcp, hdcp->displays[i].index);942 }943 944 if (hdcp_cmd->hdcp_status == TA_HDCP_STATUS__SUCCESS)945 status = MOD_HDCP_STATUS_SUCCESS;946 else947 status = MOD_HDCP_STATUS_HDCP2_ENABLE_STREAM_ENCRYPTION_FAILURE;948 949 mutex_unlock(&psp->hdcp_context.mutex);950 return status;951}952 953enum mod_hdcp_status mod_hdcp_hdcp2_prepare_stream_management(struct mod_hdcp *hdcp)954{955 956 struct psp_context *psp = hdcp->config.psp.handle;957 struct ta_hdcp_shared_memory *hdcp_cmd;958 struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;959 struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;960 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;961 962 mutex_lock(&psp->hdcp_context.mutex);963 hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;964 memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));965 966 msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2;967 msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2;968 969 hdcp2_message_init(hdcp, msg_in);970 971 msg_in->prepare.msg1_id = TA_HDCP_HDCP2_MSG_ID__REPEATERAUTH_STREAM_MANAGE;972 973 974 hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2;975 psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);976 977 if (hdcp_cmd->hdcp_status != TA_HDCP_STATUS__SUCCESS) {978 status = MOD_HDCP_STATUS_HDCP2_PREPARE_STREAM_MANAGEMENT_FAILURE;979 } else {980 hdcp->auth.msg.hdcp2.stream_manage_size = msg_out->prepare.msg1_desc.msg_size;981 982 memcpy(hdcp->auth.msg.hdcp2.repeater_auth_stream_manage,983 &msg_out->prepare.transmitter_message[0],984 sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_manage));985 }986 mutex_unlock(&psp->hdcp_context.mutex);987 return status;988}989 990enum mod_hdcp_status mod_hdcp_hdcp2_validate_stream_ready(struct mod_hdcp *hdcp)991{992 struct psp_context *psp = hdcp->config.psp.handle;993 struct ta_hdcp_shared_memory *hdcp_cmd;994 struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_input_v2 *msg_in;995 struct ta_hdcp_cmd_hdcp2_process_prepare_authentication_message_output_v2 *msg_out;996 enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;997 998 mutex_lock(&psp->hdcp_context.mutex);999 hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;1000 memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));1001 1002 msg_in = &hdcp_cmd->in_msg.hdcp2_prepare_process_authentication_message_v2;1003 msg_out = &hdcp_cmd->out_msg.hdcp2_prepare_process_authentication_message_v2;1004 1005 hdcp2_message_init(hdcp, msg_in);1006 1007 msg_in->process.msg1_desc.msg_id = TA_HDCP_HDCP2_MSG_ID__REPEATERAUTH_STREAM_READY;1008 1009 msg_in->process.msg1_desc.msg_size = sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready);1010 1011 memcpy(&msg_in->process.receiver_message[0], hdcp->auth.msg.hdcp2.repeater_auth_stream_ready,1012 sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready));1013 1014 hdcp_cmd->cmd_id = TA_HDCP_COMMAND__HDCP2_PREPARE_PROCESS_AUTHENTICATION_MSG_V2;1015 psp_hdcp_invoke(psp, hdcp_cmd->cmd_id);1016 1017 if (hdcp_cmd->hdcp_status == TA_HDCP_STATUS__SUCCESS &&1018 msg_out->process.msg1_status == TA_HDCP2_MSG_AUTHENTICATION_STATUS__SUCCESS)1019 status = MOD_HDCP_STATUS_SUCCESS;1020 else1021 status = MOD_HDCP_STATUS_HDCP2_VALIDATE_STREAM_READY_FAILURE;1022 1023 mutex_unlock(&psp->hdcp_context.mutex);1024 return status;1025}1026