1c349dbc7Sjsg /* 2c349dbc7Sjsg * Copyright 2019 Advanced Micro Devices, Inc. 3c349dbc7Sjsg * 4c349dbc7Sjsg * Permission is hereby granted, free of charge, to any person obtaining a 5c349dbc7Sjsg * copy of this software and associated documentation files (the "Software"), 6c349dbc7Sjsg * to deal in the Software without restriction, including without limitation 7c349dbc7Sjsg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8c349dbc7Sjsg * and/or sell copies of the Software, and to permit persons to whom the 9c349dbc7Sjsg * Software is furnished to do so, subject to the following conditions: 10c349dbc7Sjsg * 11c349dbc7Sjsg * The above copyright notice and this permission notice shall be included in 12c349dbc7Sjsg * all copies or substantial portions of the Software. 13c349dbc7Sjsg * 14c349dbc7Sjsg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15c349dbc7Sjsg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16c349dbc7Sjsg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17c349dbc7Sjsg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18c349dbc7Sjsg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19c349dbc7Sjsg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20c349dbc7Sjsg * OTHER DEALINGS IN THE SOFTWARE. 21c349dbc7Sjsg * 22c349dbc7Sjsg * Authors: AMD 23c349dbc7Sjsg * 24c349dbc7Sjsg */ 25c349dbc7Sjsg 26c349dbc7Sjsg #include "hdcp.h" 27c349dbc7Sjsg 28c349dbc7Sjsg #ifdef __linux__ 29c349dbc7Sjsg #define MIN(a, b) ((a) < (b) ? (a) : (b)) 30c349dbc7Sjsg #endif 31c349dbc7Sjsg #define HDCP_I2C_ADDR 0x3a /* 0x74 >> 1*/ 32c349dbc7Sjsg #define KSV_READ_SIZE 0xf /* 0x6803b - 0x6802c */ 33c349dbc7Sjsg #define HDCP_MAX_AUX_TRANSACTION_SIZE 16 34c349dbc7Sjsg 35ad8b1aafSjsg #define DP_CP_IRQ (1 << 2) 36ad8b1aafSjsg 37c349dbc7Sjsg enum mod_hdcp_ddc_message_id { 38c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_INVALID = -1, 39c349dbc7Sjsg 40c349dbc7Sjsg /* HDCP 1.4 */ 41c349dbc7Sjsg 42c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_READ_BKSV = 0, 43c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_READ_RI_R0, 44c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_WRITE_AKSV, 45c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_WRITE_AINFO, 46c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_WRITE_AN, 47c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_READ_VH_X, 48c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_READ_VH_0, 49c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_READ_VH_1, 50c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_READ_VH_2, 51c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_READ_VH_3, 52c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_READ_VH_4, 53c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_READ_BCAPS, 54c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_READ_BSTATUS, 55c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO, 56c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_READ_BINFO, 57c349dbc7Sjsg 58c349dbc7Sjsg /* HDCP 2.2 */ 59c349dbc7Sjsg 60c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_HDCP2VERSION, 61c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_RX_CAPS, 62c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT, 63c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT, 64c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM, 65c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM, 66c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME, 67c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO, 68c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT, 69c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME, 70c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS, 71c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST, 72c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2, 73c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK, 74c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE, 75c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY, 76c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_READ_RXSTATUS, 77c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE, 78c349dbc7Sjsg 79c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_MAX 80c349dbc7Sjsg }; 81c349dbc7Sjsg 82c349dbc7Sjsg static const uint8_t hdcp_i2c_offsets[] = { 83c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_BKSV] = 0x0, 84c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_RI_R0] = 0x8, 85c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_WRITE_AKSV] = 0x10, 86c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_WRITE_AINFO] = 0x15, 87c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_WRITE_AN] = 0x18, 88c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_VH_X] = 0x20, 89c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_VH_0] = 0x20, 90c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_VH_1] = 0x24, 91c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_VH_2] = 0x28, 92c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_VH_3] = 0x2C, 93c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_VH_4] = 0x30, 94c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_BCAPS] = 0x40, 95c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_BSTATUS] = 0x41, 96c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO] = 0x43, 97c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_BINFO] = 0xFF, 98c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_HDCP2VERSION] = 0x50, 99c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT] = 0x60, 100c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT] = 0x80, 101c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM] = 0x60, 102c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM] = 0x60, 103c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME] = 0x80, 104c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO] = 0x80, 105c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT] = 0x60, 106c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = 0x80, 107c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = 0x60, 108c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = 0x80, 109c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2] = 0x80, 110c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = 0x60, 111c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = 0x60, 112c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = 0x80, 113c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_RXSTATUS] = 0x70, 114c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = 0x0 115c349dbc7Sjsg }; 116c349dbc7Sjsg 117c349dbc7Sjsg static const uint32_t hdcp_dpcd_addrs[] = { 118c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_BKSV] = 0x68000, 119c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_RI_R0] = 0x68005, 120c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_WRITE_AKSV] = 0x68007, 121c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_WRITE_AINFO] = 0x6803B, 122c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_WRITE_AN] = 0x6800c, 123c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_VH_X] = 0x68014, 124c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_VH_0] = 0x68014, 125c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_VH_1] = 0x68018, 126c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_VH_2] = 0x6801c, 127c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_VH_3] = 0x68020, 128c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_VH_4] = 0x68024, 129c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_BCAPS] = 0x68028, 130c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_BSTATUS] = 0x68029, 131c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO] = 0x6802c, 132c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_BINFO] = 0x6802a, 133c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_RX_CAPS] = 0x6921d, 134c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT] = 0x69000, 135c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT] = 0x6900b, 136c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM] = 0x69220, 137c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM] = 0x692a0, 138c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME] = 0x692c0, 139c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO] = 0x692e0, 140c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT] = 0x692f0, 141c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = 0x692f8, 142c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = 0x69318, 143c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = 0x69330, 144c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2] = 0x69340, 145c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = 0x693e0, 146c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = 0x693f0, 147c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = 0x69473, 148c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_READ_RXSTATUS] = 0x69493, 149c349dbc7Sjsg [MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = 0x69494 150c349dbc7Sjsg }; 151c349dbc7Sjsg 152c349dbc7Sjsg static enum mod_hdcp_status read(struct mod_hdcp *hdcp, 153c349dbc7Sjsg enum mod_hdcp_ddc_message_id msg_id, 154c349dbc7Sjsg uint8_t *buf, 155c349dbc7Sjsg uint32_t buf_len) 156c349dbc7Sjsg { 157c349dbc7Sjsg bool success = true; 158c349dbc7Sjsg uint32_t cur_size = 0; 159c349dbc7Sjsg uint32_t data_offset = 0; 160c349dbc7Sjsg 161*2a65b6dfSjsg if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID || 162*2a65b6dfSjsg msg_id >= MOD_HDCP_MESSAGE_ID_MAX) 1632bf33035Sjsg return MOD_HDCP_STATUS_DDC_FAILURE; 1642bf33035Sjsg 165c349dbc7Sjsg if (is_dp_hdcp(hdcp)) { 166*2a65b6dfSjsg int num_dpcd_addrs = sizeof(hdcp_dpcd_addrs) / 167*2a65b6dfSjsg sizeof(hdcp_dpcd_addrs[0]); 168*2a65b6dfSjsg if (msg_id >= num_dpcd_addrs) 169*2a65b6dfSjsg return MOD_HDCP_STATUS_DDC_FAILURE; 170*2a65b6dfSjsg 171c349dbc7Sjsg while (buf_len > 0) { 172c349dbc7Sjsg cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE); 173c349dbc7Sjsg success = hdcp->config.ddc.funcs.read_dpcd(hdcp->config.ddc.handle, 174c349dbc7Sjsg hdcp_dpcd_addrs[msg_id] + data_offset, 175c349dbc7Sjsg buf + data_offset, 176c349dbc7Sjsg cur_size); 177c349dbc7Sjsg 178c349dbc7Sjsg if (!success) 179c349dbc7Sjsg break; 180c349dbc7Sjsg 181c349dbc7Sjsg buf_len -= cur_size; 182c349dbc7Sjsg data_offset += cur_size; 183c349dbc7Sjsg } 184c349dbc7Sjsg } else { 185*2a65b6dfSjsg int num_i2c_offsets = sizeof(hdcp_i2c_offsets) / 186*2a65b6dfSjsg sizeof(hdcp_i2c_offsets[0]); 187*2a65b6dfSjsg if (msg_id >= num_i2c_offsets) 188*2a65b6dfSjsg return MOD_HDCP_STATUS_DDC_FAILURE; 189*2a65b6dfSjsg 190c349dbc7Sjsg success = hdcp->config.ddc.funcs.read_i2c( 191c349dbc7Sjsg hdcp->config.ddc.handle, 192c349dbc7Sjsg HDCP_I2C_ADDR, 193c349dbc7Sjsg hdcp_i2c_offsets[msg_id], 194c349dbc7Sjsg buf, 195c349dbc7Sjsg (uint32_t)buf_len); 196c349dbc7Sjsg } 197c349dbc7Sjsg 198c349dbc7Sjsg return success ? MOD_HDCP_STATUS_SUCCESS : MOD_HDCP_STATUS_DDC_FAILURE; 199c349dbc7Sjsg } 200c349dbc7Sjsg 201c349dbc7Sjsg static enum mod_hdcp_status read_repeatedly(struct mod_hdcp *hdcp, 202c349dbc7Sjsg enum mod_hdcp_ddc_message_id msg_id, 203c349dbc7Sjsg uint8_t *buf, 204c349dbc7Sjsg uint32_t buf_len, 205c349dbc7Sjsg uint8_t read_size) 206c349dbc7Sjsg { 207c349dbc7Sjsg enum mod_hdcp_status status = MOD_HDCP_STATUS_DDC_FAILURE; 208c349dbc7Sjsg uint32_t cur_size = 0; 209c349dbc7Sjsg uint32_t data_offset = 0; 210c349dbc7Sjsg 211c349dbc7Sjsg while (buf_len > 0) { 212c349dbc7Sjsg cur_size = MIN(buf_len, read_size); 213c349dbc7Sjsg status = read(hdcp, msg_id, buf + data_offset, cur_size); 214c349dbc7Sjsg 215c349dbc7Sjsg if (status != MOD_HDCP_STATUS_SUCCESS) 216c349dbc7Sjsg break; 217c349dbc7Sjsg 218c349dbc7Sjsg buf_len -= cur_size; 219c349dbc7Sjsg data_offset += cur_size; 220c349dbc7Sjsg } 221c349dbc7Sjsg 222c349dbc7Sjsg return status; 223c349dbc7Sjsg } 224c349dbc7Sjsg 225c349dbc7Sjsg static enum mod_hdcp_status write(struct mod_hdcp *hdcp, 226c349dbc7Sjsg enum mod_hdcp_ddc_message_id msg_id, 227c349dbc7Sjsg uint8_t *buf, 228c349dbc7Sjsg uint32_t buf_len) 229c349dbc7Sjsg { 230c349dbc7Sjsg bool success = true; 231c349dbc7Sjsg uint32_t cur_size = 0; 232c349dbc7Sjsg uint32_t data_offset = 0; 233c349dbc7Sjsg 234*2a65b6dfSjsg if (msg_id == MOD_HDCP_MESSAGE_ID_INVALID || 235*2a65b6dfSjsg msg_id >= MOD_HDCP_MESSAGE_ID_MAX) 2362bf33035Sjsg return MOD_HDCP_STATUS_DDC_FAILURE; 2372bf33035Sjsg 238c349dbc7Sjsg if (is_dp_hdcp(hdcp)) { 239*2a65b6dfSjsg int num_dpcd_addrs = sizeof(hdcp_dpcd_addrs) / 240*2a65b6dfSjsg sizeof(hdcp_dpcd_addrs[0]); 241*2a65b6dfSjsg if (msg_id >= num_dpcd_addrs) 242*2a65b6dfSjsg return MOD_HDCP_STATUS_DDC_FAILURE; 243*2a65b6dfSjsg 244c349dbc7Sjsg while (buf_len > 0) { 245c349dbc7Sjsg cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE); 246c349dbc7Sjsg success = hdcp->config.ddc.funcs.write_dpcd( 247c349dbc7Sjsg hdcp->config.ddc.handle, 248c349dbc7Sjsg hdcp_dpcd_addrs[msg_id] + data_offset, 249c349dbc7Sjsg buf + data_offset, 250c349dbc7Sjsg cur_size); 251c349dbc7Sjsg 252c349dbc7Sjsg if (!success) 253c349dbc7Sjsg break; 254c349dbc7Sjsg 255c349dbc7Sjsg buf_len -= cur_size; 256c349dbc7Sjsg data_offset += cur_size; 257c349dbc7Sjsg } 258c349dbc7Sjsg } else { 259*2a65b6dfSjsg int num_i2c_offsets = sizeof(hdcp_i2c_offsets) / 260*2a65b6dfSjsg sizeof(hdcp_i2c_offsets[0]); 261*2a65b6dfSjsg if (msg_id >= num_i2c_offsets) 262*2a65b6dfSjsg return MOD_HDCP_STATUS_DDC_FAILURE; 263*2a65b6dfSjsg 264c349dbc7Sjsg hdcp->buf[0] = hdcp_i2c_offsets[msg_id]; 265c349dbc7Sjsg memmove(&hdcp->buf[1], buf, buf_len); 266c349dbc7Sjsg success = hdcp->config.ddc.funcs.write_i2c( 267c349dbc7Sjsg hdcp->config.ddc.handle, 268c349dbc7Sjsg HDCP_I2C_ADDR, 269c349dbc7Sjsg hdcp->buf, 270c349dbc7Sjsg (uint32_t)(buf_len+1)); 271c349dbc7Sjsg } 272c349dbc7Sjsg 273c349dbc7Sjsg return success ? MOD_HDCP_STATUS_SUCCESS : MOD_HDCP_STATUS_DDC_FAILURE; 274c349dbc7Sjsg } 275c349dbc7Sjsg 276c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_bksv(struct mod_hdcp *hdcp) 277c349dbc7Sjsg { 278c349dbc7Sjsg return read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BKSV, 279c349dbc7Sjsg hdcp->auth.msg.hdcp1.bksv, 280c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp1.bksv)); 281c349dbc7Sjsg } 282c349dbc7Sjsg 283c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_bcaps(struct mod_hdcp *hdcp) 284c349dbc7Sjsg { 285c349dbc7Sjsg return read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BCAPS, 286c349dbc7Sjsg &hdcp->auth.msg.hdcp1.bcaps, 287c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp1.bcaps)); 288c349dbc7Sjsg } 289c349dbc7Sjsg 290c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_bstatus(struct mod_hdcp *hdcp) 291c349dbc7Sjsg { 292c349dbc7Sjsg enum mod_hdcp_status status; 293c349dbc7Sjsg 294c349dbc7Sjsg if (is_dp_hdcp(hdcp)) 295c349dbc7Sjsg status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BSTATUS, 296c349dbc7Sjsg (uint8_t *)&hdcp->auth.msg.hdcp1.bstatus, 297c349dbc7Sjsg 1); 298c349dbc7Sjsg else 299c349dbc7Sjsg status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BSTATUS, 300c349dbc7Sjsg (uint8_t *)&hdcp->auth.msg.hdcp1.bstatus, 301c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp1.bstatus)); 302c349dbc7Sjsg return status; 303c349dbc7Sjsg } 304c349dbc7Sjsg 305c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_r0p(struct mod_hdcp *hdcp) 306c349dbc7Sjsg { 307c349dbc7Sjsg return read(hdcp, MOD_HDCP_MESSAGE_ID_READ_RI_R0, 308c349dbc7Sjsg (uint8_t *)&hdcp->auth.msg.hdcp1.r0p, 309c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp1.r0p)); 310c349dbc7Sjsg } 311c349dbc7Sjsg 312c349dbc7Sjsg /* special case, reading repeatedly at the same address, don't use read() */ 313c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_ksvlist(struct mod_hdcp *hdcp) 314c349dbc7Sjsg { 315c349dbc7Sjsg enum mod_hdcp_status status; 316c349dbc7Sjsg 317c349dbc7Sjsg if (is_dp_hdcp(hdcp)) 318c349dbc7Sjsg status = read_repeatedly(hdcp, MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO, 319c349dbc7Sjsg hdcp->auth.msg.hdcp1.ksvlist, 320c349dbc7Sjsg hdcp->auth.msg.hdcp1.ksvlist_size, 321c349dbc7Sjsg KSV_READ_SIZE); 322c349dbc7Sjsg else 323c349dbc7Sjsg status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO, 324c349dbc7Sjsg (uint8_t *)&hdcp->auth.msg.hdcp1.ksvlist, 325c349dbc7Sjsg hdcp->auth.msg.hdcp1.ksvlist_size); 326c349dbc7Sjsg return status; 327c349dbc7Sjsg } 328c349dbc7Sjsg 329c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_vp(struct mod_hdcp *hdcp) 330c349dbc7Sjsg { 331c349dbc7Sjsg enum mod_hdcp_status status; 332c349dbc7Sjsg 333c349dbc7Sjsg status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_0, 334c349dbc7Sjsg &hdcp->auth.msg.hdcp1.vp[0], 4); 335c349dbc7Sjsg if (status != MOD_HDCP_STATUS_SUCCESS) 336c349dbc7Sjsg goto out; 337c349dbc7Sjsg 338c349dbc7Sjsg status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_1, 339c349dbc7Sjsg &hdcp->auth.msg.hdcp1.vp[4], 4); 340c349dbc7Sjsg if (status != MOD_HDCP_STATUS_SUCCESS) 341c349dbc7Sjsg goto out; 342c349dbc7Sjsg 343c349dbc7Sjsg status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_2, 344c349dbc7Sjsg &hdcp->auth.msg.hdcp1.vp[8], 4); 345c349dbc7Sjsg if (status != MOD_HDCP_STATUS_SUCCESS) 346c349dbc7Sjsg goto out; 347c349dbc7Sjsg 348c349dbc7Sjsg status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_3, 349c349dbc7Sjsg &hdcp->auth.msg.hdcp1.vp[12], 4); 350c349dbc7Sjsg if (status != MOD_HDCP_STATUS_SUCCESS) 351c349dbc7Sjsg goto out; 352c349dbc7Sjsg 353c349dbc7Sjsg status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_4, 354c349dbc7Sjsg &hdcp->auth.msg.hdcp1.vp[16], 4); 355c349dbc7Sjsg out: 356c349dbc7Sjsg return status; 357c349dbc7Sjsg } 358c349dbc7Sjsg 359c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_binfo(struct mod_hdcp *hdcp) 360c349dbc7Sjsg { 361c349dbc7Sjsg enum mod_hdcp_status status; 362c349dbc7Sjsg 363c349dbc7Sjsg if (is_dp_hdcp(hdcp)) 364c349dbc7Sjsg status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BINFO, 365c349dbc7Sjsg (uint8_t *)&hdcp->auth.msg.hdcp1.binfo_dp, 366c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp1.binfo_dp)); 367c349dbc7Sjsg else 368c349dbc7Sjsg status = MOD_HDCP_STATUS_INVALID_OPERATION; 369c349dbc7Sjsg 370c349dbc7Sjsg return status; 371c349dbc7Sjsg } 372c349dbc7Sjsg 373c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_write_aksv(struct mod_hdcp *hdcp) 374c349dbc7Sjsg { 375c349dbc7Sjsg return write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKSV, 376c349dbc7Sjsg hdcp->auth.msg.hdcp1.aksv, 377c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp1.aksv)); 378c349dbc7Sjsg } 379c349dbc7Sjsg 380c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_write_ainfo(struct mod_hdcp *hdcp) 381c349dbc7Sjsg { 382c349dbc7Sjsg return write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AINFO, 383c349dbc7Sjsg &hdcp->auth.msg.hdcp1.ainfo, 384c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp1.ainfo)); 385c349dbc7Sjsg } 386c349dbc7Sjsg 387c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_write_an(struct mod_hdcp *hdcp) 388c349dbc7Sjsg { 389c349dbc7Sjsg return write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AN, 390c349dbc7Sjsg hdcp->auth.msg.hdcp1.an, 391c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp1.an)); 392c349dbc7Sjsg } 393c349dbc7Sjsg 394c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_hdcp2version(struct mod_hdcp *hdcp) 395c349dbc7Sjsg { 396c349dbc7Sjsg enum mod_hdcp_status status; 397c349dbc7Sjsg 398c349dbc7Sjsg if (is_dp_hdcp(hdcp)) 399c349dbc7Sjsg status = MOD_HDCP_STATUS_INVALID_OPERATION; 400c349dbc7Sjsg else 401c349dbc7Sjsg status = read(hdcp, MOD_HDCP_MESSAGE_ID_HDCP2VERSION, 402c349dbc7Sjsg &hdcp->auth.msg.hdcp2.hdcp2version_hdmi, 403c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp2.hdcp2version_hdmi)); 404c349dbc7Sjsg 405c349dbc7Sjsg return status; 406c349dbc7Sjsg } 407c349dbc7Sjsg 408c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_rxcaps(struct mod_hdcp *hdcp) 409c349dbc7Sjsg { 410c349dbc7Sjsg enum mod_hdcp_status status; 411c349dbc7Sjsg 412c349dbc7Sjsg if (!is_dp_hdcp(hdcp)) 413c349dbc7Sjsg status = MOD_HDCP_STATUS_INVALID_OPERATION; 414c349dbc7Sjsg else 415c349dbc7Sjsg status = read(hdcp, MOD_HDCP_MESSAGE_ID_RX_CAPS, 416c349dbc7Sjsg hdcp->auth.msg.hdcp2.rxcaps_dp, 417c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp2.rxcaps_dp)); 418c349dbc7Sjsg 419c349dbc7Sjsg return status; 420c349dbc7Sjsg } 421c349dbc7Sjsg 422c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_rxstatus(struct mod_hdcp *hdcp) 423c349dbc7Sjsg { 424c349dbc7Sjsg enum mod_hdcp_status status; 425c349dbc7Sjsg 426c349dbc7Sjsg if (is_dp_hdcp(hdcp)) { 427c349dbc7Sjsg status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_RXSTATUS, 428c349dbc7Sjsg &hdcp->auth.msg.hdcp2.rxstatus_dp, 429c349dbc7Sjsg 1); 430c349dbc7Sjsg } else { 431c349dbc7Sjsg status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_RXSTATUS, 432c349dbc7Sjsg (uint8_t *)&hdcp->auth.msg.hdcp2.rxstatus, 433c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp2.rxstatus)); 434c349dbc7Sjsg } 435c349dbc7Sjsg return status; 436c349dbc7Sjsg } 437c349dbc7Sjsg 438c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_ake_cert(struct mod_hdcp *hdcp) 439c349dbc7Sjsg { 440c349dbc7Sjsg enum mod_hdcp_status status; 441c349dbc7Sjsg 442c349dbc7Sjsg if (is_dp_hdcp(hdcp)) { 443c349dbc7Sjsg hdcp->auth.msg.hdcp2.ake_cert[0] = HDCP_2_2_AKE_SEND_CERT; 444c349dbc7Sjsg status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT, 445c349dbc7Sjsg hdcp->auth.msg.hdcp2.ake_cert+1, 446c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp2.ake_cert)-1); 447c349dbc7Sjsg 448c349dbc7Sjsg } else { 449c349dbc7Sjsg status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT, 450c349dbc7Sjsg hdcp->auth.msg.hdcp2.ake_cert, 451c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp2.ake_cert)); 452c349dbc7Sjsg } 453c349dbc7Sjsg return status; 454c349dbc7Sjsg } 455c349dbc7Sjsg 456c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_h_prime(struct mod_hdcp *hdcp) 457c349dbc7Sjsg { 458c349dbc7Sjsg enum mod_hdcp_status status; 459c349dbc7Sjsg 460c349dbc7Sjsg if (is_dp_hdcp(hdcp)) { 461c349dbc7Sjsg hdcp->auth.msg.hdcp2.ake_h_prime[0] = HDCP_2_2_AKE_SEND_HPRIME; 462c349dbc7Sjsg status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME, 463c349dbc7Sjsg hdcp->auth.msg.hdcp2.ake_h_prime+1, 464c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp2.ake_h_prime)-1); 465c349dbc7Sjsg 466c349dbc7Sjsg } else { 467c349dbc7Sjsg status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME, 468c349dbc7Sjsg hdcp->auth.msg.hdcp2.ake_h_prime, 469c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp2.ake_h_prime)); 470c349dbc7Sjsg } 471c349dbc7Sjsg return status; 472c349dbc7Sjsg } 473c349dbc7Sjsg 474c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_pairing_info(struct mod_hdcp *hdcp) 475c349dbc7Sjsg { 476c349dbc7Sjsg enum mod_hdcp_status status; 477c349dbc7Sjsg 478c349dbc7Sjsg if (is_dp_hdcp(hdcp)) { 479c349dbc7Sjsg hdcp->auth.msg.hdcp2.ake_pairing_info[0] = HDCP_2_2_AKE_SEND_PAIRING_INFO; 480c349dbc7Sjsg status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO, 481c349dbc7Sjsg hdcp->auth.msg.hdcp2.ake_pairing_info+1, 482c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp2.ake_pairing_info)-1); 483c349dbc7Sjsg 484c349dbc7Sjsg } else { 485c349dbc7Sjsg status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO, 486c349dbc7Sjsg hdcp->auth.msg.hdcp2.ake_pairing_info, 487c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp2.ake_pairing_info)); 488c349dbc7Sjsg } 489c349dbc7Sjsg return status; 490c349dbc7Sjsg } 491c349dbc7Sjsg 492c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_l_prime(struct mod_hdcp *hdcp) 493c349dbc7Sjsg { 494c349dbc7Sjsg enum mod_hdcp_status status; 495c349dbc7Sjsg 496c349dbc7Sjsg if (is_dp_hdcp(hdcp)) { 497c349dbc7Sjsg hdcp->auth.msg.hdcp2.lc_l_prime[0] = HDCP_2_2_LC_SEND_LPRIME; 498c349dbc7Sjsg status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME, 499c349dbc7Sjsg hdcp->auth.msg.hdcp2.lc_l_prime+1, 500c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp2.lc_l_prime)-1); 501c349dbc7Sjsg 502c349dbc7Sjsg } else { 503c349dbc7Sjsg status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME, 504c349dbc7Sjsg hdcp->auth.msg.hdcp2.lc_l_prime, 505c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp2.lc_l_prime)); 506c349dbc7Sjsg } 507c349dbc7Sjsg return status; 508c349dbc7Sjsg } 509c349dbc7Sjsg 510c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_rx_id_list(struct mod_hdcp *hdcp) 511c349dbc7Sjsg { 512c349dbc7Sjsg enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS; 513c349dbc7Sjsg 514c349dbc7Sjsg if (is_dp_hdcp(hdcp)) { 515c349dbc7Sjsg uint32_t device_count = 0; 516c349dbc7Sjsg uint32_t rx_id_list_size = 0; 517c349dbc7Sjsg uint32_t bytes_read = 0; 518c349dbc7Sjsg 519c349dbc7Sjsg hdcp->auth.msg.hdcp2.rx_id_list[0] = HDCP_2_2_REP_SEND_RECVID_LIST; 520c349dbc7Sjsg status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST, 521c349dbc7Sjsg hdcp->auth.msg.hdcp2.rx_id_list+1, 522c349dbc7Sjsg HDCP_MAX_AUX_TRANSACTION_SIZE); 523c349dbc7Sjsg if (status == MOD_HDCP_STATUS_SUCCESS) { 524c349dbc7Sjsg bytes_read = HDCP_MAX_AUX_TRANSACTION_SIZE; 525c349dbc7Sjsg device_count = HDCP_2_2_DEV_COUNT_LO(hdcp->auth.msg.hdcp2.rx_id_list[2]) + 526c349dbc7Sjsg (HDCP_2_2_DEV_COUNT_HI(hdcp->auth.msg.hdcp2.rx_id_list[1]) << 4); 527c349dbc7Sjsg rx_id_list_size = MIN((21 + 5 * device_count), 528c349dbc7Sjsg (sizeof(hdcp->auth.msg.hdcp2.rx_id_list) - 1)); 529c349dbc7Sjsg status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST_PART2, 530c349dbc7Sjsg hdcp->auth.msg.hdcp2.rx_id_list + 1 + bytes_read, 531c349dbc7Sjsg (rx_id_list_size - 1) / HDCP_MAX_AUX_TRANSACTION_SIZE * HDCP_MAX_AUX_TRANSACTION_SIZE); 532c349dbc7Sjsg } 533c349dbc7Sjsg } else { 534c349dbc7Sjsg status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST, 535c349dbc7Sjsg hdcp->auth.msg.hdcp2.rx_id_list, 536c349dbc7Sjsg hdcp->auth.msg.hdcp2.rx_id_list_size); 537c349dbc7Sjsg } 538c349dbc7Sjsg return status; 539c349dbc7Sjsg } 540c349dbc7Sjsg 541c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_read_stream_ready(struct mod_hdcp *hdcp) 542c349dbc7Sjsg { 543c349dbc7Sjsg enum mod_hdcp_status status; 544c349dbc7Sjsg 545c349dbc7Sjsg if (is_dp_hdcp(hdcp)) { 546c349dbc7Sjsg hdcp->auth.msg.hdcp2.repeater_auth_stream_ready[0] = HDCP_2_2_REP_STREAM_READY; 547c349dbc7Sjsg status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY, 548c349dbc7Sjsg hdcp->auth.msg.hdcp2.repeater_auth_stream_ready+1, 549c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready)-1); 550c349dbc7Sjsg 551c349dbc7Sjsg } else { 552c349dbc7Sjsg status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY, 553c349dbc7Sjsg hdcp->auth.msg.hdcp2.repeater_auth_stream_ready, 554c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready)); 555c349dbc7Sjsg } 556c349dbc7Sjsg return status; 557c349dbc7Sjsg } 558c349dbc7Sjsg 559c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_write_ake_init(struct mod_hdcp *hdcp) 560c349dbc7Sjsg { 561c349dbc7Sjsg enum mod_hdcp_status status; 562c349dbc7Sjsg 563c349dbc7Sjsg if (is_dp_hdcp(hdcp)) 564c349dbc7Sjsg status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT, 565c349dbc7Sjsg hdcp->auth.msg.hdcp2.ake_init+1, 566c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp2.ake_init)-1); 567c349dbc7Sjsg else 568c349dbc7Sjsg status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT, 569c349dbc7Sjsg hdcp->auth.msg.hdcp2.ake_init, 570c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp2.ake_init)); 571c349dbc7Sjsg return status; 572c349dbc7Sjsg } 573c349dbc7Sjsg 574c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_write_no_stored_km(struct mod_hdcp *hdcp) 575c349dbc7Sjsg { 576c349dbc7Sjsg enum mod_hdcp_status status; 577c349dbc7Sjsg 578c349dbc7Sjsg if (is_dp_hdcp(hdcp)) 579c349dbc7Sjsg status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM, 580c349dbc7Sjsg hdcp->auth.msg.hdcp2.ake_no_stored_km+1, 581c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km)-1); 582c349dbc7Sjsg else 583c349dbc7Sjsg status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM, 584c349dbc7Sjsg hdcp->auth.msg.hdcp2.ake_no_stored_km, 585c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km)); 586c349dbc7Sjsg return status; 587c349dbc7Sjsg } 588c349dbc7Sjsg 589c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_write_stored_km(struct mod_hdcp *hdcp) 590c349dbc7Sjsg { 591c349dbc7Sjsg enum mod_hdcp_status status; 592c349dbc7Sjsg 593c349dbc7Sjsg if (is_dp_hdcp(hdcp)) 594c349dbc7Sjsg status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM, 595c349dbc7Sjsg hdcp->auth.msg.hdcp2.ake_stored_km+1, 596c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp2.ake_stored_km)-1); 597c349dbc7Sjsg else 598c349dbc7Sjsg status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM, 599c349dbc7Sjsg hdcp->auth.msg.hdcp2.ake_stored_km, 600c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp2.ake_stored_km)); 601c349dbc7Sjsg return status; 602c349dbc7Sjsg } 603c349dbc7Sjsg 604c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_write_lc_init(struct mod_hdcp *hdcp) 605c349dbc7Sjsg { 606c349dbc7Sjsg enum mod_hdcp_status status; 607c349dbc7Sjsg 608c349dbc7Sjsg if (is_dp_hdcp(hdcp)) 609c349dbc7Sjsg status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT, 610c349dbc7Sjsg hdcp->auth.msg.hdcp2.lc_init+1, 611c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp2.lc_init)-1); 612c349dbc7Sjsg else 613c349dbc7Sjsg status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT, 614c349dbc7Sjsg hdcp->auth.msg.hdcp2.lc_init, 615c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp2.lc_init)); 616c349dbc7Sjsg return status; 617c349dbc7Sjsg } 618c349dbc7Sjsg 619c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_write_eks(struct mod_hdcp *hdcp) 620c349dbc7Sjsg { 621c349dbc7Sjsg enum mod_hdcp_status status; 622c349dbc7Sjsg 623c349dbc7Sjsg if (is_dp_hdcp(hdcp)) 624c349dbc7Sjsg status = write(hdcp, 625c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS, 626c349dbc7Sjsg hdcp->auth.msg.hdcp2.ske_eks+1, 627c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp2.ske_eks)-1); 628c349dbc7Sjsg else 629c349dbc7Sjsg status = write(hdcp, 630c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS, 631c349dbc7Sjsg hdcp->auth.msg.hdcp2.ske_eks, 632c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp2.ske_eks)); 633c349dbc7Sjsg return status; 634c349dbc7Sjsg } 635c349dbc7Sjsg 636c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_write_repeater_auth_ack(struct mod_hdcp *hdcp) 637c349dbc7Sjsg { 638c349dbc7Sjsg enum mod_hdcp_status status; 639c349dbc7Sjsg 640c349dbc7Sjsg if (is_dp_hdcp(hdcp)) 641c349dbc7Sjsg status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK, 642c349dbc7Sjsg hdcp->auth.msg.hdcp2.repeater_auth_ack+1, 643c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp2.repeater_auth_ack)-1); 644c349dbc7Sjsg else 645c349dbc7Sjsg status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK, 646c349dbc7Sjsg hdcp->auth.msg.hdcp2.repeater_auth_ack, 647c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp2.repeater_auth_ack)); 648c349dbc7Sjsg return status; 649c349dbc7Sjsg } 650c349dbc7Sjsg 651c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_write_stream_manage(struct mod_hdcp *hdcp) 652c349dbc7Sjsg { 653c349dbc7Sjsg enum mod_hdcp_status status; 654c349dbc7Sjsg 655c349dbc7Sjsg if (is_dp_hdcp(hdcp)) 656c349dbc7Sjsg status = write(hdcp, 657c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE, 658c349dbc7Sjsg hdcp->auth.msg.hdcp2.repeater_auth_stream_manage+1, 659c349dbc7Sjsg hdcp->auth.msg.hdcp2.stream_manage_size-1); 660c349dbc7Sjsg else 661c349dbc7Sjsg status = write(hdcp, 662c349dbc7Sjsg MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE, 663c349dbc7Sjsg hdcp->auth.msg.hdcp2.repeater_auth_stream_manage, 664c349dbc7Sjsg hdcp->auth.msg.hdcp2.stream_manage_size); 665c349dbc7Sjsg return status; 666c349dbc7Sjsg } 667c349dbc7Sjsg 668c349dbc7Sjsg enum mod_hdcp_status mod_hdcp_write_content_type(struct mod_hdcp *hdcp) 669c349dbc7Sjsg { 670c349dbc7Sjsg enum mod_hdcp_status status; 671c349dbc7Sjsg 672c349dbc7Sjsg if (is_dp_hdcp(hdcp)) 673c349dbc7Sjsg status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE, 674c349dbc7Sjsg hdcp->auth.msg.hdcp2.content_stream_type_dp+1, 675c349dbc7Sjsg sizeof(hdcp->auth.msg.hdcp2.content_stream_type_dp)-1); 676c349dbc7Sjsg else 677c349dbc7Sjsg status = MOD_HDCP_STATUS_INVALID_OPERATION; 678c349dbc7Sjsg return status; 679c349dbc7Sjsg } 680ad8b1aafSjsg 681ad8b1aafSjsg enum mod_hdcp_status mod_hdcp_clear_cp_irq_status(struct mod_hdcp *hdcp) 682ad8b1aafSjsg { 683ad8b1aafSjsg uint8_t clear_cp_irq_bit = DP_CP_IRQ; 684ad8b1aafSjsg uint32_t size = 1; 685ad8b1aafSjsg 686ad8b1aafSjsg if (is_dp_hdcp(hdcp)) { 687ad8b1aafSjsg uint32_t cp_irq_addrs = (hdcp->connection.link.dp.rev >= 0x14) 688ad8b1aafSjsg ? DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0:DP_DEVICE_SERVICE_IRQ_VECTOR; 689ad8b1aafSjsg return hdcp->config.ddc.funcs.write_dpcd(hdcp->config.ddc.handle, cp_irq_addrs, 690ad8b1aafSjsg &clear_cp_irq_bit, size) ? MOD_HDCP_STATUS_SUCCESS : MOD_HDCP_STATUS_DDC_FAILURE; 691ad8b1aafSjsg } 692ad8b1aafSjsg 693ad8b1aafSjsg return MOD_HDCP_STATUS_INVALID_OPERATION; 694ad8b1aafSjsg } 695