1 // SPDX-License-Identifier: (GPL-2.0) 2 /* 3 * Copyright © 2019 Intel Corporation 4 * 5 * Mei_hdcp.c: HDCP client driver for mei bus 6 * 7 * Author: 8 * Ramalingam C <ramalingam.c@intel.com> 9 */ 10 11 /** 12 * DOC: MEI_HDCP Client Driver 13 * 14 * This is a client driver to the mei_bus to make the HDCP2.2 services of 15 * ME FW available for the interested consumers like I915. 16 * 17 * This module will act as a translation layer between HDCP protocol 18 * implementor(I915) and ME FW by translating HDCP2.2 authentication 19 * messages to ME FW command payloads and vice versa. 20 */ 21 22 #include <linux/module.h> 23 #include <linux/slab.h> 24 #include <linux/uuid.h> 25 #include <linux/mei_cl_bus.h> 26 #include <drm/drm_connector.h> 27 #include <drm/i915_component.h> 28 #include <drm/i915_mei_hdcp_interface.h> 29 30 #include "mei_hdcp.h" 31 32 static inline u8 mei_get_ddi_index(enum port port) 33 { 34 switch (port) { 35 case PORT_A: 36 return MEI_DDI_A; 37 case PORT_B ... PORT_F: 38 return (u8)port; 39 default: 40 return MEI_DDI_INVALID_PORT; 41 } 42 } 43 44 /** 45 * mei_hdcp_initiate_session() - Initiate a Wired HDCP2.2 Tx Session in ME FW 46 * @dev: device corresponding to the mei_cl_device 47 * @data: Intel HW specific hdcp data 48 * @ake_data: AKE_Init msg output. 49 * 50 * Return: 0 on Success, <0 on Failure. 51 */ 52 static int 53 mei_hdcp_initiate_session(struct device *dev, struct hdcp_port_data *data, 54 struct hdcp2_ake_init *ake_data) 55 { 56 struct wired_cmd_initiate_hdcp2_session_in session_init_in = { { 0 } }; 57 struct wired_cmd_initiate_hdcp2_session_out 58 session_init_out = { { 0 } }; 59 struct mei_cl_device *cldev; 60 ssize_t byte; 61 62 if (!dev || !data || !ake_data) 63 return -EINVAL; 64 65 cldev = to_mei_cl_device(dev); 66 67 session_init_in.header.api_version = HDCP_API_VERSION; 68 session_init_in.header.command_id = WIRED_INITIATE_HDCP2_SESSION; 69 session_init_in.header.status = ME_HDCP_STATUS_SUCCESS; 70 session_init_in.header.buffer_len = 71 WIRED_CMD_BUF_LEN_INITIATE_HDCP2_SESSION_IN; 72 73 session_init_in.port.integrated_port_type = data->port_type; 74 session_init_in.port.physical_port = mei_get_ddi_index(data->port); 75 session_init_in.protocol = data->protocol; 76 77 byte = mei_cldev_send(cldev, (u8 *)&session_init_in, 78 sizeof(session_init_in)); 79 if (byte < 0) { 80 dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte); 81 return byte; 82 } 83 84 byte = mei_cldev_recv(cldev, (u8 *)&session_init_out, 85 sizeof(session_init_out)); 86 if (byte < 0) { 87 dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte); 88 return byte; 89 } 90 91 if (session_init_out.header.status != ME_HDCP_STATUS_SUCCESS) { 92 dev_dbg(dev, "ME cmd 0x%08X Failed. Status: 0x%X\n", 93 WIRED_INITIATE_HDCP2_SESSION, 94 session_init_out.header.status); 95 return -EIO; 96 } 97 98 ake_data->msg_id = HDCP_2_2_AKE_INIT; 99 ake_data->tx_caps = session_init_out.tx_caps; 100 memcpy(ake_data->r_tx, session_init_out.r_tx, HDCP_2_2_RTX_LEN); 101 102 return 0; 103 } 104 105 /** 106 * mei_hdcp_verify_receiver_cert_prepare_km() - Verify the Receiver Certificate 107 * AKE_Send_Cert and prepare AKE_Stored_Km/AKE_No_Stored_Km 108 * @dev: device corresponding to the mei_cl_device 109 * @data: Intel HW specific hdcp data 110 * @rx_cert: AKE_Send_Cert for verification 111 * @km_stored: Pairing status flag output 112 * @ek_pub_km: AKE_Stored_Km/AKE_No_Stored_Km output msg 113 * @msg_sz : size of AKE_XXXXX_Km output msg 114 * 115 * Return: 0 on Success, <0 on Failure 116 */ 117 static int 118 mei_hdcp_verify_receiver_cert_prepare_km(struct device *dev, 119 struct hdcp_port_data *data, 120 struct hdcp2_ake_send_cert *rx_cert, 121 bool *km_stored, 122 struct hdcp2_ake_no_stored_km 123 *ek_pub_km, 124 size_t *msg_sz) 125 { 126 struct wired_cmd_verify_receiver_cert_in verify_rxcert_in = { { 0 } }; 127 struct wired_cmd_verify_receiver_cert_out verify_rxcert_out = { { 0 } }; 128 struct mei_cl_device *cldev; 129 ssize_t byte; 130 131 if (!dev || !data || !rx_cert || !km_stored || !ek_pub_km || !msg_sz) 132 return -EINVAL; 133 134 cldev = to_mei_cl_device(dev); 135 136 verify_rxcert_in.header.api_version = HDCP_API_VERSION; 137 verify_rxcert_in.header.command_id = WIRED_VERIFY_RECEIVER_CERT; 138 verify_rxcert_in.header.status = ME_HDCP_STATUS_SUCCESS; 139 verify_rxcert_in.header.buffer_len = 140 WIRED_CMD_BUF_LEN_VERIFY_RECEIVER_CERT_IN; 141 142 verify_rxcert_in.port.integrated_port_type = data->port_type; 143 verify_rxcert_in.port.physical_port = mei_get_ddi_index(data->port); 144 145 verify_rxcert_in.cert_rx = rx_cert->cert_rx; 146 memcpy(verify_rxcert_in.r_rx, &rx_cert->r_rx, HDCP_2_2_RRX_LEN); 147 memcpy(verify_rxcert_in.rx_caps, rx_cert->rx_caps, HDCP_2_2_RXCAPS_LEN); 148 149 byte = mei_cldev_send(cldev, (u8 *)&verify_rxcert_in, 150 sizeof(verify_rxcert_in)); 151 if (byte < 0) { 152 dev_dbg(dev, "mei_cldev_send failed: %zd\n", byte); 153 return byte; 154 } 155 156 byte = mei_cldev_recv(cldev, (u8 *)&verify_rxcert_out, 157 sizeof(verify_rxcert_out)); 158 if (byte < 0) { 159 dev_dbg(dev, "mei_cldev_recv failed: %zd\n", byte); 160 return byte; 161 } 162 163 if (verify_rxcert_out.header.status != ME_HDCP_STATUS_SUCCESS) { 164 dev_dbg(dev, "ME cmd 0x%08X Failed. Status: 0x%X\n", 165 WIRED_VERIFY_RECEIVER_CERT, 166 verify_rxcert_out.header.status); 167 return -EIO; 168 } 169 170 *km_stored = !!verify_rxcert_out.km_stored; 171 if (verify_rxcert_out.km_stored) { 172 ek_pub_km->msg_id = HDCP_2_2_AKE_STORED_KM; 173 *msg_sz = sizeof(struct hdcp2_ake_stored_km); 174 } else { 175 ek_pub_km->msg_id = HDCP_2_2_AKE_NO_STORED_KM; 176 *msg_sz = sizeof(struct hdcp2_ake_no_stored_km); 177 } 178 179 memcpy(ek_pub_km->e_kpub_km, &verify_rxcert_out.ekm_buff, 180 sizeof(verify_rxcert_out.ekm_buff)); 181 182 return 0; 183 } 184 185 /** 186 * mei_hdcp_verify_hprime() - Verify AKE_Send_H_prime at ME FW. 187 * @dev: device corresponding to the mei_cl_device 188 * @data: Intel HW specific hdcp data 189 * @rx_hprime: AKE_Send_H_prime msg for ME FW verification 190 * 191 * Return: 0 on Success, <0 on Failure 192 */ 193 static int 194 mei_hdcp_verify_hprime(struct device *dev, struct hdcp_port_data *data, 195 struct hdcp2_ake_send_hprime *rx_hprime) 196 { 197 struct wired_cmd_ake_send_hprime_in send_hprime_in = { { 0 } }; 198 struct wired_cmd_ake_send_hprime_out send_hprime_out = { { 0 } }; 199 struct mei_cl_device *cldev; 200 ssize_t byte; 201 202 if (!dev || !data || !rx_hprime) 203 return -EINVAL; 204 205 cldev = to_mei_cl_device(dev); 206 207 send_hprime_in.header.api_version = HDCP_API_VERSION; 208 send_hprime_in.header.command_id = WIRED_AKE_SEND_HPRIME; 209 send_hprime_in.header.status = ME_HDCP_STATUS_SUCCESS; 210 send_hprime_in.header.buffer_len = WIRED_CMD_BUF_LEN_AKE_SEND_HPRIME_IN; 211 212 send_hprime_in.port.integrated_port_type = data->port_type; 213 send_hprime_in.port.physical_port = mei_get_ddi_index(data->port); 214 215 memcpy(send_hprime_in.h_prime, rx_hprime->h_prime, 216 HDCP_2_2_H_PRIME_LEN); 217 218 byte = mei_cldev_send(cldev, (u8 *)&send_hprime_in, 219 sizeof(send_hprime_in)); 220 if (byte < 0) { 221 dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte); 222 return byte; 223 } 224 225 byte = mei_cldev_recv(cldev, (u8 *)&send_hprime_out, 226 sizeof(send_hprime_out)); 227 if (byte < 0) { 228 dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte); 229 return byte; 230 } 231 232 if (send_hprime_out.header.status != ME_HDCP_STATUS_SUCCESS) { 233 dev_dbg(dev, "ME cmd 0x%08X Failed. Status: 0x%X\n", 234 WIRED_AKE_SEND_HPRIME, send_hprime_out.header.status); 235 return -EIO; 236 } 237 238 return 0; 239 } 240 241 /** 242 * mei_hdcp_store_pairing_info() - Store pairing info received at ME FW 243 * @dev: device corresponding to the mei_cl_device 244 * @data: Intel HW specific hdcp data 245 * @pairing_info: AKE_Send_Pairing_Info msg input to ME FW 246 * 247 * Return: 0 on Success, <0 on Failure 248 */ 249 static int 250 mei_hdcp_store_pairing_info(struct device *dev, struct hdcp_port_data *data, 251 struct hdcp2_ake_send_pairing_info *pairing_info) 252 { 253 struct wired_cmd_ake_send_pairing_info_in pairing_info_in = { { 0 } }; 254 struct wired_cmd_ake_send_pairing_info_out pairing_info_out = { { 0 } }; 255 struct mei_cl_device *cldev; 256 ssize_t byte; 257 258 if (!dev || !data || !pairing_info) 259 return -EINVAL; 260 261 cldev = to_mei_cl_device(dev); 262 263 pairing_info_in.header.api_version = HDCP_API_VERSION; 264 pairing_info_in.header.command_id = WIRED_AKE_SEND_PAIRING_INFO; 265 pairing_info_in.header.status = ME_HDCP_STATUS_SUCCESS; 266 pairing_info_in.header.buffer_len = 267 WIRED_CMD_BUF_LEN_SEND_PAIRING_INFO_IN; 268 269 pairing_info_in.port.integrated_port_type = data->port_type; 270 pairing_info_in.port.physical_port = mei_get_ddi_index(data->port); 271 272 memcpy(pairing_info_in.e_kh_km, pairing_info->e_kh_km, 273 HDCP_2_2_E_KH_KM_LEN); 274 275 byte = mei_cldev_send(cldev, (u8 *)&pairing_info_in, 276 sizeof(pairing_info_in)); 277 if (byte < 0) { 278 dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte); 279 return byte; 280 } 281 282 byte = mei_cldev_recv(cldev, (u8 *)&pairing_info_out, 283 sizeof(pairing_info_out)); 284 if (byte < 0) { 285 dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte); 286 return byte; 287 } 288 289 if (pairing_info_out.header.status != ME_HDCP_STATUS_SUCCESS) { 290 dev_dbg(dev, "ME cmd 0x%08X failed. Status: 0x%X\n", 291 WIRED_AKE_SEND_PAIRING_INFO, 292 pairing_info_out.header.status); 293 return -EIO; 294 } 295 296 return 0; 297 } 298 299 /** 300 * mei_hdcp_initiate_locality_check() - Prepare LC_Init 301 * @dev: device corresponding to the mei_cl_device 302 * @data: Intel HW specific hdcp data 303 * @lc_init_data: LC_Init msg output 304 * 305 * Return: 0 on Success, <0 on Failure 306 */ 307 static int 308 mei_hdcp_initiate_locality_check(struct device *dev, 309 struct hdcp_port_data *data, 310 struct hdcp2_lc_init *lc_init_data) 311 { 312 struct wired_cmd_init_locality_check_in lc_init_in = { { 0 } }; 313 struct wired_cmd_init_locality_check_out lc_init_out = { { 0 } }; 314 struct mei_cl_device *cldev; 315 ssize_t byte; 316 317 if (!dev || !data || !lc_init_data) 318 return -EINVAL; 319 320 cldev = to_mei_cl_device(dev); 321 322 lc_init_in.header.api_version = HDCP_API_VERSION; 323 lc_init_in.header.command_id = WIRED_INIT_LOCALITY_CHECK; 324 lc_init_in.header.status = ME_HDCP_STATUS_SUCCESS; 325 lc_init_in.header.buffer_len = WIRED_CMD_BUF_LEN_INIT_LOCALITY_CHECK_IN; 326 327 lc_init_in.port.integrated_port_type = data->port_type; 328 lc_init_in.port.physical_port = mei_get_ddi_index(data->port); 329 330 byte = mei_cldev_send(cldev, (u8 *)&lc_init_in, sizeof(lc_init_in)); 331 if (byte < 0) { 332 dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte); 333 return byte; 334 } 335 336 byte = mei_cldev_recv(cldev, (u8 *)&lc_init_out, sizeof(lc_init_out)); 337 if (byte < 0) { 338 dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte); 339 return byte; 340 } 341 342 if (lc_init_out.header.status != ME_HDCP_STATUS_SUCCESS) { 343 dev_dbg(dev, "ME cmd 0x%08X Failed. status: 0x%X\n", 344 WIRED_INIT_LOCALITY_CHECK, lc_init_out.header.status); 345 return -EIO; 346 } 347 348 lc_init_data->msg_id = HDCP_2_2_LC_INIT; 349 memcpy(lc_init_data->r_n, lc_init_out.r_n, HDCP_2_2_RN_LEN); 350 351 return 0; 352 } 353 354 /** 355 * mei_hdcp_verify_lprime() - Verify lprime. 356 * @dev: device corresponding to the mei_cl_device 357 * @data: Intel HW specific hdcp data 358 * @rx_lprime: LC_Send_L_prime msg for ME FW verification 359 * 360 * Return: 0 on Success, <0 on Failure 361 */ 362 static int 363 mei_hdcp_verify_lprime(struct device *dev, struct hdcp_port_data *data, 364 struct hdcp2_lc_send_lprime *rx_lprime) 365 { 366 struct wired_cmd_validate_locality_in verify_lprime_in = { { 0 } }; 367 struct wired_cmd_validate_locality_out verify_lprime_out = { { 0 } }; 368 struct mei_cl_device *cldev; 369 ssize_t byte; 370 371 if (!dev || !data || !rx_lprime) 372 return -EINVAL; 373 374 cldev = to_mei_cl_device(dev); 375 376 verify_lprime_in.header.api_version = HDCP_API_VERSION; 377 verify_lprime_in.header.command_id = WIRED_VALIDATE_LOCALITY; 378 verify_lprime_in.header.status = ME_HDCP_STATUS_SUCCESS; 379 verify_lprime_in.header.buffer_len = 380 WIRED_CMD_BUF_LEN_VALIDATE_LOCALITY_IN; 381 382 verify_lprime_in.port.integrated_port_type = data->port_type; 383 verify_lprime_in.port.physical_port = mei_get_ddi_index(data->port); 384 385 memcpy(verify_lprime_in.l_prime, rx_lprime->l_prime, 386 HDCP_2_2_L_PRIME_LEN); 387 388 byte = mei_cldev_send(cldev, (u8 *)&verify_lprime_in, 389 sizeof(verify_lprime_in)); 390 if (byte < 0) { 391 dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte); 392 return byte; 393 } 394 395 byte = mei_cldev_recv(cldev, (u8 *)&verify_lprime_out, 396 sizeof(verify_lprime_out)); 397 if (byte < 0) { 398 dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte); 399 return byte; 400 } 401 402 if (verify_lprime_out.header.status != ME_HDCP_STATUS_SUCCESS) { 403 dev_dbg(dev, "ME cmd 0x%08X failed. status: 0x%X\n", 404 WIRED_VALIDATE_LOCALITY, 405 verify_lprime_out.header.status); 406 return -EIO; 407 } 408 409 return 0; 410 } 411 412 /** 413 * mei_hdcp_get_session_key() - Prepare SKE_Send_Eks. 414 * @dev: device corresponding to the mei_cl_device 415 * @data: Intel HW specific hdcp data 416 * @ske_data: SKE_Send_Eks msg output from ME FW. 417 * 418 * Return: 0 on Success, <0 on Failure 419 */ 420 static int mei_hdcp_get_session_key(struct device *dev, 421 struct hdcp_port_data *data, 422 struct hdcp2_ske_send_eks *ske_data) 423 { 424 struct wired_cmd_get_session_key_in get_skey_in = { { 0 } }; 425 struct wired_cmd_get_session_key_out get_skey_out = { { 0 } }; 426 struct mei_cl_device *cldev; 427 ssize_t byte; 428 429 if (!dev || !data || !ske_data) 430 return -EINVAL; 431 432 cldev = to_mei_cl_device(dev); 433 434 get_skey_in.header.api_version = HDCP_API_VERSION; 435 get_skey_in.header.command_id = WIRED_GET_SESSION_KEY; 436 get_skey_in.header.status = ME_HDCP_STATUS_SUCCESS; 437 get_skey_in.header.buffer_len = WIRED_CMD_BUF_LEN_GET_SESSION_KEY_IN; 438 439 get_skey_in.port.integrated_port_type = data->port_type; 440 get_skey_in.port.physical_port = mei_get_ddi_index(data->port); 441 442 byte = mei_cldev_send(cldev, (u8 *)&get_skey_in, sizeof(get_skey_in)); 443 if (byte < 0) { 444 dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte); 445 return byte; 446 } 447 448 byte = mei_cldev_recv(cldev, (u8 *)&get_skey_out, sizeof(get_skey_out)); 449 450 if (byte < 0) { 451 dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte); 452 return byte; 453 } 454 455 if (get_skey_out.header.status != ME_HDCP_STATUS_SUCCESS) { 456 dev_dbg(dev, "ME cmd 0x%08X failed. status: 0x%X\n", 457 WIRED_GET_SESSION_KEY, get_skey_out.header.status); 458 return -EIO; 459 } 460 461 ske_data->msg_id = HDCP_2_2_SKE_SEND_EKS; 462 memcpy(ske_data->e_dkey_ks, get_skey_out.e_dkey_ks, 463 HDCP_2_2_E_DKEY_KS_LEN); 464 memcpy(ske_data->riv, get_skey_out.r_iv, HDCP_2_2_RIV_LEN); 465 466 return 0; 467 } 468 469 /** 470 * mei_hdcp_repeater_check_flow_prepare_ack() - Validate the Downstream topology 471 * and prepare rep_ack. 472 * @dev: device corresponding to the mei_cl_device 473 * @data: Intel HW specific hdcp data 474 * @rep_topology: Receiver ID List to be validated 475 * @rep_send_ack : repeater ack from ME FW. 476 * 477 * Return: 0 on Success, <0 on Failure 478 */ 479 static int 480 mei_hdcp_repeater_check_flow_prepare_ack(struct device *dev, 481 struct hdcp_port_data *data, 482 struct hdcp2_rep_send_receiverid_list 483 *rep_topology, 484 struct hdcp2_rep_send_ack 485 *rep_send_ack) 486 { 487 struct wired_cmd_verify_repeater_in verify_repeater_in = { { 0 } }; 488 struct wired_cmd_verify_repeater_out verify_repeater_out = { { 0 } }; 489 struct mei_cl_device *cldev; 490 ssize_t byte; 491 492 if (!dev || !rep_topology || !rep_send_ack || !data) 493 return -EINVAL; 494 495 cldev = to_mei_cl_device(dev); 496 497 verify_repeater_in.header.api_version = HDCP_API_VERSION; 498 verify_repeater_in.header.command_id = WIRED_VERIFY_REPEATER; 499 verify_repeater_in.header.status = ME_HDCP_STATUS_SUCCESS; 500 verify_repeater_in.header.buffer_len = 501 WIRED_CMD_BUF_LEN_VERIFY_REPEATER_IN; 502 503 verify_repeater_in.port.integrated_port_type = data->port_type; 504 verify_repeater_in.port.physical_port = mei_get_ddi_index(data->port); 505 506 memcpy(verify_repeater_in.rx_info, rep_topology->rx_info, 507 HDCP_2_2_RXINFO_LEN); 508 memcpy(verify_repeater_in.seq_num_v, rep_topology->seq_num_v, 509 HDCP_2_2_SEQ_NUM_LEN); 510 memcpy(verify_repeater_in.v_prime, rep_topology->v_prime, 511 HDCP_2_2_V_PRIME_HALF_LEN); 512 memcpy(verify_repeater_in.receiver_ids, rep_topology->receiver_ids, 513 HDCP_2_2_RECEIVER_IDS_MAX_LEN); 514 515 byte = mei_cldev_send(cldev, (u8 *)&verify_repeater_in, 516 sizeof(verify_repeater_in)); 517 if (byte < 0) { 518 dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte); 519 return byte; 520 } 521 522 byte = mei_cldev_recv(cldev, (u8 *)&verify_repeater_out, 523 sizeof(verify_repeater_out)); 524 if (byte < 0) { 525 dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte); 526 return byte; 527 } 528 529 if (verify_repeater_out.header.status != ME_HDCP_STATUS_SUCCESS) { 530 dev_dbg(dev, "ME cmd 0x%08X failed. status: 0x%X\n", 531 WIRED_VERIFY_REPEATER, 532 verify_repeater_out.header.status); 533 return -EIO; 534 } 535 536 memcpy(rep_send_ack->v, verify_repeater_out.v, 537 HDCP_2_2_V_PRIME_HALF_LEN); 538 rep_send_ack->msg_id = HDCP_2_2_REP_SEND_ACK; 539 540 return 0; 541 } 542 543 /** 544 * mei_hdcp_verify_mprime() - Verify mprime. 545 * @dev: device corresponding to the mei_cl_device 546 * @data: Intel HW specific hdcp data 547 * @stream_ready: RepeaterAuth_Stream_Ready msg for ME FW verification. 548 * 549 * Return: 0 on Success, <0 on Failure 550 */ 551 static int mei_hdcp_verify_mprime(struct device *dev, 552 struct hdcp_port_data *data, 553 struct hdcp2_rep_stream_ready *stream_ready) 554 { 555 struct wired_cmd_repeater_auth_stream_req_in 556 verify_mprime_in = { { 0 } }; 557 struct wired_cmd_repeater_auth_stream_req_out 558 verify_mprime_out = { { 0 } }; 559 struct mei_cl_device *cldev; 560 ssize_t byte; 561 562 if (!dev || !stream_ready || !data) 563 return -EINVAL; 564 565 cldev = to_mei_cl_device(dev); 566 567 verify_mprime_in.header.api_version = HDCP_API_VERSION; 568 verify_mprime_in.header.command_id = WIRED_REPEATER_AUTH_STREAM_REQ; 569 verify_mprime_in.header.status = ME_HDCP_STATUS_SUCCESS; 570 verify_mprime_in.header.buffer_len = 571 WIRED_CMD_BUF_LEN_REPEATER_AUTH_STREAM_REQ_MIN_IN; 572 573 verify_mprime_in.port.integrated_port_type = data->port_type; 574 verify_mprime_in.port.physical_port = mei_get_ddi_index(data->port); 575 576 memcpy(verify_mprime_in.m_prime, stream_ready->m_prime, 577 HDCP_2_2_MPRIME_LEN); 578 drm_hdcp2_u32_to_seq_num(verify_mprime_in.seq_num_m, data->seq_num_m); 579 memcpy(verify_mprime_in.streams, data->streams, 580 (data->k * sizeof(struct hdcp2_streamid_type))); 581 582 verify_mprime_in.k = cpu_to_be16(data->k); 583 584 byte = mei_cldev_send(cldev, (u8 *)&verify_mprime_in, 585 sizeof(verify_mprime_in)); 586 if (byte < 0) { 587 dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte); 588 return byte; 589 } 590 591 byte = mei_cldev_recv(cldev, (u8 *)&verify_mprime_out, 592 sizeof(verify_mprime_out)); 593 if (byte < 0) { 594 dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte); 595 return byte; 596 } 597 598 if (verify_mprime_out.header.status != ME_HDCP_STATUS_SUCCESS) { 599 dev_dbg(dev, "ME cmd 0x%08X failed. status: 0x%X\n", 600 WIRED_REPEATER_AUTH_STREAM_REQ, 601 verify_mprime_out.header.status); 602 return -EIO; 603 } 604 605 return 0; 606 } 607 608 /** 609 * mei_hdcp_enable_authentication() - Mark a port as authenticated 610 * through ME FW 611 * @dev: device corresponding to the mei_cl_device 612 * @data: Intel HW specific hdcp data 613 * 614 * Return: 0 on Success, <0 on Failure 615 */ 616 static int mei_hdcp_enable_authentication(struct device *dev, 617 struct hdcp_port_data *data) 618 { 619 struct wired_cmd_enable_auth_in enable_auth_in = { { 0 } }; 620 struct wired_cmd_enable_auth_out enable_auth_out = { { 0 } }; 621 struct mei_cl_device *cldev; 622 ssize_t byte; 623 624 if (!dev || !data) 625 return -EINVAL; 626 627 cldev = to_mei_cl_device(dev); 628 629 enable_auth_in.header.api_version = HDCP_API_VERSION; 630 enable_auth_in.header.command_id = WIRED_ENABLE_AUTH; 631 enable_auth_in.header.status = ME_HDCP_STATUS_SUCCESS; 632 enable_auth_in.header.buffer_len = WIRED_CMD_BUF_LEN_ENABLE_AUTH_IN; 633 634 enable_auth_in.port.integrated_port_type = data->port_type; 635 enable_auth_in.port.physical_port = mei_get_ddi_index(data->port); 636 enable_auth_in.stream_type = data->streams[0].stream_type; 637 638 byte = mei_cldev_send(cldev, (u8 *)&enable_auth_in, 639 sizeof(enable_auth_in)); 640 if (byte < 0) { 641 dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte); 642 return byte; 643 } 644 645 byte = mei_cldev_recv(cldev, (u8 *)&enable_auth_out, 646 sizeof(enable_auth_out)); 647 if (byte < 0) { 648 dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte); 649 return byte; 650 } 651 652 if (enable_auth_out.header.status != ME_HDCP_STATUS_SUCCESS) { 653 dev_dbg(dev, "ME cmd 0x%08X failed. status: 0x%X\n", 654 WIRED_ENABLE_AUTH, enable_auth_out.header.status); 655 return -EIO; 656 } 657 658 return 0; 659 } 660 661 /** 662 * mei_hdcp_close_session() - Close the Wired HDCP Tx session of ME FW per port. 663 * This also disables the authenticated state of the port. 664 * @dev: device corresponding to the mei_cl_device 665 * @data: Intel HW specific hdcp data 666 * 667 * Return: 0 on Success, <0 on Failure 668 */ 669 static int 670 mei_hdcp_close_session(struct device *dev, struct hdcp_port_data *data) 671 { 672 struct wired_cmd_close_session_in session_close_in = { { 0 } }; 673 struct wired_cmd_close_session_out session_close_out = { { 0 } }; 674 struct mei_cl_device *cldev; 675 ssize_t byte; 676 677 if (!dev || !data) 678 return -EINVAL; 679 680 cldev = to_mei_cl_device(dev); 681 682 session_close_in.header.api_version = HDCP_API_VERSION; 683 session_close_in.header.command_id = WIRED_CLOSE_SESSION; 684 session_close_in.header.status = ME_HDCP_STATUS_SUCCESS; 685 session_close_in.header.buffer_len = 686 WIRED_CMD_BUF_LEN_CLOSE_SESSION_IN; 687 688 session_close_in.port.integrated_port_type = data->port_type; 689 session_close_in.port.physical_port = mei_get_ddi_index(data->port); 690 691 byte = mei_cldev_send(cldev, (u8 *)&session_close_in, 692 sizeof(session_close_in)); 693 if (byte < 0) { 694 dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte); 695 return byte; 696 } 697 698 byte = mei_cldev_recv(cldev, (u8 *)&session_close_out, 699 sizeof(session_close_out)); 700 if (byte < 0) { 701 dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte); 702 return byte; 703 } 704 705 if (session_close_out.header.status != ME_HDCP_STATUS_SUCCESS) { 706 dev_dbg(dev, "Session Close Failed. status: 0x%X\n", 707 session_close_out.header.status); 708 return -EIO; 709 } 710 711 return 0; 712 } 713 714 static const __attribute__((unused)) 715 struct i915_hdcp_component_ops mei_hdcp_ops = { 716 .owner = THIS_MODULE, 717 .initiate_hdcp2_session = mei_hdcp_initiate_session, 718 .verify_receiver_cert_prepare_km = 719 mei_hdcp_verify_receiver_cert_prepare_km, 720 .verify_hprime = mei_hdcp_verify_hprime, 721 .store_pairing_info = mei_hdcp_store_pairing_info, 722 .initiate_locality_check = mei_hdcp_initiate_locality_check, 723 .verify_lprime = mei_hdcp_verify_lprime, 724 .get_session_key = mei_hdcp_get_session_key, 725 .repeater_check_flow_prepare_ack = 726 mei_hdcp_repeater_check_flow_prepare_ack, 727 .verify_mprime = mei_hdcp_verify_mprime, 728 .enable_hdcp_authentication = mei_hdcp_enable_authentication, 729 .close_hdcp_session = mei_hdcp_close_session, 730 }; 731 732 static int mei_hdcp_probe(struct mei_cl_device *cldev, 733 const struct mei_cl_device_id *id) 734 { 735 int ret; 736 737 ret = mei_cldev_enable(cldev); 738 if (ret < 0) 739 dev_err(&cldev->dev, "mei_cldev_enable Failed. %d\n", ret); 740 741 return ret; 742 } 743 744 static int mei_hdcp_remove(struct mei_cl_device *cldev) 745 { 746 return mei_cldev_disable(cldev); 747 } 748 749 #define MEI_UUID_HDCP GUID_INIT(0xB638AB7E, 0x94E2, 0x4EA2, 0xA5, \ 750 0x52, 0xD1, 0xC5, 0x4B, 0x62, 0x7F, 0x04) 751 752 static struct mei_cl_device_id mei_hdcp_tbl[] = { 753 { .uuid = MEI_UUID_HDCP, .version = MEI_CL_VERSION_ANY }, 754 { } 755 }; 756 MODULE_DEVICE_TABLE(mei, mei_hdcp_tbl); 757 758 static struct mei_cl_driver mei_hdcp_driver = { 759 .id_table = mei_hdcp_tbl, 760 .name = KBUILD_MODNAME, 761 .probe = mei_hdcp_probe, 762 .remove = mei_hdcp_remove, 763 }; 764 765 module_mei_cl_driver(mei_hdcp_driver); 766 767 MODULE_AUTHOR("Intel Corporation"); 768 MODULE_LICENSE("GPL"); 769 MODULE_DESCRIPTION("MEI HDCP"); 770