summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJi Soo Shin <jisshin@google.com>2023-04-18 01:06:32 +0200
committerJi Soo Shin <jisshin@google.com>2023-04-20 15:39:46 +0200
commit404329cb356ec77b41135a4d2db5e3a792d18f9e (patch)
treea9425923fb02f97ff28bae440f83027742804d5d
parent020efa21655d0a7c92cb0bdc12d6e176002e8180 (diff)
downloadsamsung-404329cb356ec77b41135a4d2db5e3a792d18f9e.tar.gz
hdcp: centralize authentication to this kernel driver.
We need centralized authentication driver that will holistically attempt HDCP2 auth then HDCP1 auth then so on. To realize this means that we need to integrate HDCP1 driver originally from DP driver side more seamlessly here and migrate even more features. This helps DP driver to have even simpler interface to HDCP. Bug: 274950373 Bug: 274517648 Change-Id: I7e11f6ea6b38abc75d0f518bf003db154870ee9d
-rw-r--r--BUILD.bazel3
-rw-r--r--Kbuild23
-rw-r--r--auth-control.c138
-rw-r--r--auth-control.h27
-rw-r--r--auth13.c (renamed from exynos-hdcp1-auth.c)104
-rw-r--r--auth13.h18
-rw-r--r--auth22-ake.c330
-rw-r--r--auth22-internal.h79
-rw-r--r--auth22-lc.c99
-rw-r--r--auth22-repeater.c135
-rw-r--r--auth22-ske.c77
-rw-r--r--auth22-stream.c106
-rw-r--r--auth22.c194
-rw-r--r--auth22.h18
-rw-r--r--dpcd.c42
-rw-r--r--dpcd.h17
-rw-r--r--exynos-hdcp-interface.h38
-rw-r--r--exynos-hdcp1-auth.h18
-rw-r--r--exynos-hdcp2-dplink-auth.c1148
-rw-r--r--exynos-hdcp2-dplink-auth.h32
-rw-r--r--exynos-hdcp2-dplink-if.c102
-rw-r--r--exynos-hdcp2-dplink-if.h63
-rw-r--r--exynos-hdcp2-dplink-inter.c181
-rw-r--r--exynos-hdcp2-dplink-inter.h34
-rw-r--r--exynos-hdcp2-dplink-protocol-msg.c492
-rw-r--r--exynos-hdcp2-dplink-protocol-msg.h77
-rw-r--r--exynos-hdcp2-dplink-reg.h51
-rw-r--r--exynos-hdcp2-dplink.c283
-rw-r--r--exynos-hdcp2-dplink.h38
-rw-r--r--exynos-hdcp2-main.c216
-rw-r--r--exynos-hdcp2-protocol-msg.c144
-rw-r--r--exynos-hdcp2-protocol-msg.h217
-rw-r--r--exynos-hdcp2-selftest.h13
-rw-r--r--exynos-hdcp2-session.c516
-rw-r--r--exynos-hdcp2-session.h122
-rw-r--r--exynos-hdcp2.h269
-rw-r--r--hdcp-log.h (renamed from exynos-hdcp2-log.h)14
-rw-r--r--main.c115
-rw-r--r--selftest.c (renamed from exynos-hdcp2-selftest.c)103
-rw-r--r--selftest.h16
-rw-r--r--teeif.c (renamed from exynos-hdcp2-teeif.c)21
-rw-r--r--teeif.h (renamed from exynos-hdcp2-teeif.h)13
42 files changed, 1600 insertions, 4146 deletions
diff --git a/BUILD.bazel b/BUILD.bazel
index 0e76ba8..d601d07 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -5,8 +5,7 @@ load("//build/kernel/kleaf:kernel.bzl", "kernel_module")
filegroup(
name = "headers",
srcs = [
- "exynos-hdcp2-dplink-inter.h",
- "exynos-hdcp2-dplink-if.h",
+ "exynos-hdcp-interface.h",
],
visibility = [
"//private/google-modules/display:__pkg__",
diff --git a/Kbuild b/Kbuild
index be4cbd0..dece7d5 100644
--- a/Kbuild
+++ b/Kbuild
@@ -5,16 +5,17 @@
ccflags-y += -I$(srctree)/include/
-exynos-hdcp2-y += exynos-hdcp1-auth.o
-exynos-hdcp2-y += exynos-hdcp2-main.o
-exynos-hdcp2-y += exynos-hdcp2-teeif.o
-exynos-hdcp2-y += exynos-hdcp2-session.o
-exynos-hdcp2-y += exynos-hdcp2-protocol-msg.o
-exynos-hdcp2-y += exynos-hdcp2-dplink-inter.o
-exynos-hdcp2-y += exynos-hdcp2-dplink.o
-exynos-hdcp2-y += exynos-hdcp2-dplink-if.o
-exynos-hdcp2-y += exynos-hdcp2-dplink-auth.o
-exynos-hdcp2-y += exynos-hdcp2-dplink-protocol-msg.o
-exynos-hdcp2-y += exynos-hdcp2-selftest.o
+exynos-hdcp2-y += auth-control.o
+exynos-hdcp2-y += auth13.o
+exynos-hdcp2-y += auth22.o
+exynos-hdcp2-y += auth22-ake.o
+exynos-hdcp2-y += auth22-lc.o
+exynos-hdcp2-y += auth22-repeater.o
+exynos-hdcp2-y += auth22-ske.o
+exynos-hdcp2-y += auth22-stream.o
+exynos-hdcp2-y += dpcd.o
+exynos-hdcp2-y += main.o
+exynos-hdcp2-y += selftest.o
+exynos-hdcp2-y += teeif.o
obj-$(CONFIG_EXYNOS_HDCP2) += exynos-hdcp2.o
diff --git a/auth-control.c b/auth-control.c
new file mode 100644
index 0000000..21527cd
--- /dev/null
+++ b/auth-control.c
@@ -0,0 +1,138 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Samsung DisplayPort driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+
+#include "exynos-hdcp-interface.h"
+
+#include "auth-control.h"
+#include "auth13.h"
+#include "auth22.h"
+#include "hdcp-log.h"
+#include "teeif.h"
+
+static struct delayed_work hdcp_work;
+
+static enum auth_state state;
+
+static unsigned long max_ver = 0; /* Disable HDCP by default */
+module_param(max_ver, ulong, 0664);
+MODULE_PARM_DESC(max_ver,
+ "support up to specific hdcp version by setting max_ver=x");
+
+int hdcp_get_auth_state(void) {
+ return state;
+}
+
+static int run_hdcp2_auth(void) {
+ int ret;
+ int i;
+
+ state = HDCP2_AUTH_PROGRESS;
+ for (i = 0; i < 5; ++i) {
+ ret = hdcp22_dplink_authenticate();
+ if (ret == 0) {
+ state = HDCP2_AUTH_DONE;
+ /* HDCP2.2 spec defined 200ms */
+ msleep(200);
+ hdcp_tee_enable_enc_22();
+ return 0;
+ } else if (ret != -EAGAIN) {
+ return -EIO;
+ }
+ hdcp_info("HDCP22 Retry...\n");
+ }
+
+ return -EIO;
+}
+
+static void hdcp_worker(struct work_struct *work) {
+ if (max_ver >= 2) {
+ hdcp_info("Trying HDCP22...\n");
+ if (run_hdcp2_auth() == 0) {
+ hdcp_info("HDCP22 Authentication Success\n");
+ return;
+ }
+ hdcp_info("HDCP22 Authentication Failed.\n");
+ } else {
+ hdcp_info("Not trying HDCP22. max_ver is %lu\n", max_ver);
+ }
+
+ if (max_ver >= 1) {
+ hdcp_info("Trying HDCP13...\n");
+ state = HDCP1_AUTH_PROGRESS;
+ if (hdcp13_dplink_authenticate() == 0) {
+ hdcp_info("HDCP13 Authentication Success\n");
+ state = HDCP1_AUTH_DONE;
+ return;
+ }
+
+ state = HDCP_AUTH_IDLE;
+ hdcp_info("HDCP13 Authentication Failed.\n");
+ } else {
+ hdcp_info("Not trying HDCP13. max_ver is %lu\n", max_ver);
+ }
+}
+
+void hdcp_dplink_handle_irq(void) {
+ if (state == HDCP2_AUTH_PROGRESS || state == HDCP2_AUTH_DONE) {
+ if (hdcp22_dplink_handle_irq() == -EAGAIN)
+ schedule_delayed_work(&hdcp_work, 0);
+ return;
+ }
+
+ if (state == HDCP1_AUTH_DONE) {
+ if (hdcp13_dplink_handle_irq() == -EAGAIN)
+ schedule_delayed_work(&hdcp_work, 0);
+ return;
+ }
+}
+EXPORT_SYMBOL_GPL(hdcp_dplink_handle_irq);
+
+
+void hdcp_dplink_connect_state(enum dp_state dp_hdcp_state) {
+ hdcp_info("Displayport connect info (%d)\n", dp_hdcp_state);
+ hdcp_tee_connect_info((int)dp_hdcp_state);
+ if (dp_hdcp_state == DP_DISCONNECT) {
+ hdcp13_dplink_abort();
+ hdcp22_dplink_abort();
+ hdcp_tee_disable_enc();
+ state = HDCP_AUTH_IDLE;
+ return;
+ }
+
+ schedule_delayed_work(&hdcp_work, msecs_to_jiffies(500));
+ return;
+}
+EXPORT_SYMBOL_GPL(hdcp_dplink_connect_state);
+
+void hdcp_auth_worker_init(void) {
+ INIT_DELAYED_WORK(&hdcp_work, hdcp_worker);
+}
+
+void hdcp_auth_worker_deinit(void) {
+ cancel_delayed_work_sync(&hdcp_work);
+}
+
+/* DEPRECATED */
+int hdcp_dplink_auth_check(enum auth_signal signal) { return -1; }
+EXPORT_SYMBOL_GPL(hdcp_dplink_auth_check);
+int hdcp_dplink_get_rxstatus(uint8_t *status) { return -1; }
+EXPORT_SYMBOL_GPL(hdcp_dplink_get_rxstatus);
+int hdcp_dplink_set_paring_available(void) { return -1; }
+EXPORT_SYMBOL_GPL(hdcp_dplink_set_paring_available);
+int hdcp_dplink_set_hprime_available(void) { return -1; }
+EXPORT_SYMBOL_GPL(hdcp_dplink_set_hprime_available);
+int hdcp_dplink_set_rp_ready(void) { return -1; }
+EXPORT_SYMBOL_GPL(hdcp_dplink_set_rp_ready);
+int hdcp_dplink_set_reauth(void) { return -1; }
+EXPORT_SYMBOL_GPL(hdcp_dplink_set_reauth);
diff --git a/auth-control.h b/auth-control.h
new file mode 100644
index 0000000..340a778
--- /dev/null
+++ b/auth-control.h
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Samsung DisplayPort driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __EXYNOS_HDCP_AUTH_CONTROL_H__
+#define __EXYNOS_HDCP_AUTH_CONTROL_H__
+
+enum auth_state {
+ HDCP_AUTH_IDLE,
+ HDCP1_AUTH_PROGRESS,
+ HDCP1_AUTH_DONE,
+ HDCP2_AUTH_PROGRESS,
+ HDCP2_AUTH_DONE,
+};
+
+int hdcp_get_auth_state(void);
+
+void hdcp_auth_worker_init(void);
+void hdcp_auth_worker_deinit(void);
+
+#endif
diff --git a/exynos-hdcp1-auth.c b/auth13.c
index 9e9b3c9..f29628a 100644
--- a/exynos-hdcp1-auth.c
+++ b/auth13.c
@@ -14,11 +14,13 @@
#include <drm/drm_dp_helper.h>
-#include "exynos-hdcp1-auth.h"
-#include "exynos-hdcp2.h"
-#include "exynos-hdcp2-dplink-if.h"
-#include "exynos-hdcp2-log.h"
-#include "exynos-hdcp2-teeif.h"
+#include "exynos-hdcp-interface.h"
+
+#include "auth-control.h"
+#include "auth13.h"
+#include "dpcd.h"
+#include "hdcp-log.h"
+#include "teeif.h"
#define HDCP_R0_SIZE 2
#define HDCP_BKSV_SIZE 5
@@ -35,8 +37,7 @@
#define MAX_DEVS_EXCEEDED (0x00000080)
#define BKSV_LIST_FIFO_SIZE (15)
-extern enum dp_state dp_hdcp_state;
-extern enum auth_state auth_proc_state;
+static bool is_aborted = false;
static int compare_rprime(void)
{
@@ -46,7 +47,7 @@ static int compare_rprime(void)
usleep_range(RI_DELAY * 1000, RI_DELAY * 1000 + 1);
- ret = hdcp_dplink_recv(HDCP13_MSG_BSTATUS_R, &bstatus,
+ ret = hdcp_dplink_recv(DP_AUX_HDCP_BSTATUS, &bstatus,
sizeof(bstatus));
if (ret || !(bstatus & DP_BSTATUS_R0_PRIME_READY)) {
hdcp_err("BSTATUS read err ret(%d) bstatus(%d)\n",
@@ -56,7 +57,7 @@ static int compare_rprime(void)
hdcp_info("R0-Prime is ready in HDCP Receiver\n");
do {
- ret = hdcp_dplink_recv(HDCP13_MSG_RI_PRIME_R, (uint8_t*)&rprime,
+ ret = hdcp_dplink_recv(DP_AUX_HDCP_RI_PRIME, (uint8_t*)&rprime,
HDCP_R0_SIZE);
if (!ret) {
ret = teei_verify_r_prime(rprime);
@@ -81,7 +82,7 @@ static int read_ksv_list(u8* hdcp_ksv, u32 len)
uint32_t read_len = len < BKSV_LIST_FIFO_SIZE ?
len : BKSV_LIST_FIFO_SIZE;
- return hdcp_dplink_recv(HDCP13_MSG_KSV_FIFO_R, hdcp_ksv, read_len) ?
+ return hdcp_dplink_recv(DP_AUX_HDCP_KSV_FIFO, hdcp_ksv, read_len) ?
-EIO : read_len;
}
@@ -106,13 +107,13 @@ static int proceed_repeater(void)
usleep_range(RI_AVAILABLE_WAITING * 1000, RI_AVAILABLE_WAITING * 1000 + 1);
waiting_time_ms = (s64)((ktime_get() - start_time_ns) / 1000000);
if ((waiting_time_ms >= REPEATER_READY_MAX_WAIT_DELAY) ||
- (dp_hdcp_state == DP_DISCONNECT)) {
+ is_aborted) {
hdcp_err("Not repeater ready in RX part %lld\n",
waiting_time_ms);
return -EINVAL;
}
- ret = hdcp_dplink_recv(HDCP13_MSG_BSTATUS_R, &bstatus,
+ ret = hdcp_dplink_recv(DP_AUX_HDCP_BSTATUS, &bstatus,
sizeof(bstatus));
if (ret) {
hdcp_err("Read BSTATUS failed (%d)\n", ret);
@@ -121,10 +122,10 @@ static int proceed_repeater(void)
} while (!(bstatus & DP_BSTATUS_READY));
hdcp_info("Ready HDCP RX Repeater!!!\n");
- if (dp_hdcp_state == DP_DISCONNECT)
+ if (is_aborted)
return -EINVAL;
- ret = hdcp_dplink_recv(HDCP13_MSG_BINFO_R, (uint8_t*)&binfo, HDCP_BINFO_SIZE);
+ ret = hdcp_dplink_recv(DP_AUX_HDCP_BINFO, (uint8_t*)&binfo, HDCP_BINFO_SIZE);
if (ret) {
hdcp_err("Read BINFO failed (%d)\n", ret);
return -EIO;
@@ -152,7 +153,7 @@ static int proceed_repeater(void)
}
do {
- ret = hdcp_dplink_recv(HDCP13_MSG_VPRIME_R, vprime,
+ ret = hdcp_dplink_recv(DP_AUX_HDCP_V_PRIME(0), vprime,
HDCP_SHA1_SIZE);
if (!ret) {
ret = teei_verify_v_prime(binfo, ksv_list,
@@ -173,67 +174,92 @@ static int proceed_repeater(void)
return -EIO;
}
-void hdcp13_dplink_authenticate(void)
+int hdcp13_dplink_authenticate(void)
{
uint64_t aksv, bksv, an;
uint8_t bcaps;
int ret;
hdcp_info("Start SW Authentication\n");
+ is_aborted = false;
+
+ aksv = bksv = an = 0;
- if (dp_hdcp_state == DP_DISCONNECT) {
- hdcp_err("DP is disconnected\n");
- return;
+ ret = hdcp_dplink_recv(DP_AUX_HDCP_BCAPS, &bcaps, sizeof(bcaps));
+ if (ret) {
+ hdcp_err("BCaps Read failure (%d)\n", ret);
+ return -EIO;
}
- auth_proc_state = HDCP_AUTH_PROCESS_IDLE;
+ if (!(bcaps & DP_BCAPS_HDCP_CAPABLE)) {
+ hdcp_err("HDCP13 is not supported\n");
+ return -EIO;
+ }
- aksv = bksv = an = 0;
- ret = hdcp_dplink_recv(HDCP13_MSG_BKSV_R, (uint8_t*)&bksv, HDCP_BKSV_SIZE);
+ ret = hdcp_dplink_recv(DP_AUX_HDCP_BKSV, (uint8_t*)&bksv, HDCP_BKSV_SIZE);
if (ret) {
hdcp_err("Read Bksv failed (%d)\n", ret);
- return;
+ return -EIO;
}
- ret = teei_ksv_exchange(bksv, &aksv, &an);
+ ret = teei_ksv_exchange(bksv, bcaps & DP_BCAPS_REPEATER_PRESENT,
+ &aksv, &an);
if (ret) {
hdcp_err("Ksv exchange failed (%d)\n", ret);
- return;
+ return -EIO;
}
- ret = hdcp_dplink_send(HDCP13_MSG_AN_W, (uint8_t*)&an, HDCP_AN_SIZE);
+ ret = hdcp_dplink_send(DP_AUX_HDCP_AN, (uint8_t*)&an, HDCP_AN_SIZE);
if (ret) {
hdcp_err("Write AN failed (%d)\n", ret);
- return;
+ return -EIO;
}
- ret = hdcp_dplink_send(HDCP13_MSG_AKSV_W, (uint8_t*)&aksv, HDCP_AKSV_SIZE);
+ ret = hdcp_dplink_send(DP_AUX_HDCP_AKSV, (uint8_t*)&aksv, HDCP_AKSV_SIZE);
if (ret) {
hdcp_err("Write AKSV failed (%d)\n", ret);
- return;
+ return -EIO;
}
if (compare_rprime() != 0) {
hdcp_err("R0 is not same\n");
- return;
+ return -EIO;
}
hdcp_tee_enable_enc_13();
hdcp_info("Done 1st Authentication\n");
- ret = hdcp_dplink_recv(HDCP13_MSG_BCAPS_R, (uint8_t*)&bcaps, sizeof(bcaps));
- if (ret) {
- hdcp_err("BCaps Read failure (%d)\n", ret);
- return;
- }
-
if ((bcaps & DP_BCAPS_REPEATER_PRESENT) && proceed_repeater()) {
hdcp_err("HDCP Authentication fail!!!\n");
hdcp_tee_disable_enc();
- return;
+ return -EIO;
}
- auth_proc_state = HDCP1_AUTH_PROCESS_DONE;
hdcp_info("Done SW Authentication\n");
- return;
+ return 0;
+}
+
+int hdcp13_dplink_abort(void) {
+ is_aborted = true;
+ return 0;
}
+int hdcp13_dplink_handle_irq(void)
+{
+ uint8_t bstatus;
+
+ if (hdcp_get_auth_state() != HDCP1_AUTH_DONE) {
+ hdcp_err("Ignoring IRQ during auth\n");
+ return 0;
+ }
+
+ hdcp_dplink_recv(DP_AUX_HDCP_BSTATUS, &bstatus, sizeof(bstatus));
+
+ if (bstatus & DP_BSTATUS_LINK_FAILURE ||
+ bstatus & DP_BSTATUS_REAUTH_REQ) {
+ hdcp_err("Resetting link and encryption\n");
+ hdcp_tee_disable_enc();
+ return -EAGAIN;
+ }
+
+ return 0;
+}
diff --git a/auth13.h b/auth13.h
new file mode 100644
index 0000000..cb70628
--- /dev/null
+++ b/auth13.h
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Samsung DisplayPort driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __EXYNOS_HDCP1_AUTH_H__
+#define __EXYNOS_HDCP1_AUTH_H__
+
+int hdcp13_dplink_authenticate(void);
+int hdcp13_dplink_abort(void);
+int hdcp13_dplink_handle_irq(void);
+
+#endif
diff --git a/auth22-ake.c b/auth22-ake.c
new file mode 100644
index 0000000..58f6b5f
--- /dev/null
+++ b/auth22-ake.c
@@ -0,0 +1,330 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Samsung DisplayPort driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <drm/drm_dp_helper.h>
+#include <linux/kernel.h>
+
+#include "auth22-internal.h"
+#include "dpcd.h"
+#include "teeif.h"
+#include "hdcp-log.h"
+
+static int do_send_ake_init(struct hdcp_link_data *lk)
+{
+ int ret;
+ uint8_t rtx[HDCP_AKE_RTX_BYTE_LEN];
+ uint8_t txcaps[HDCP_CAPS_BYTE_LEN];
+
+ if (lk->is_aborted)
+ return -ECANCELED;
+
+ /* Generate rtx */
+ ret = teei_gen_rtx(HDCP_LINK_TYPE_DP, rtx, sizeof(rtx),
+ txcaps, sizeof(txcaps));
+ if (ret) {
+ hdcp_err("teei_gen_rtx failed (%d)\n", ret);
+ return -EIO;
+ }
+
+ ret = hdcp_dplink_send(DP_HDCP_2_2_REG_RTX_OFFSET, rtx, sizeof(rtx));
+ if (ret) {
+ hdcp_err("rtx send fail: ret(%d)\n", ret);
+ return -EIO;
+ }
+
+ ret = hdcp_dplink_send(DP_HDCP_2_2_REG_TXCAPS_OFFSET, txcaps,
+ sizeof(txcaps));
+ if (ret) {
+ hdcp_err("txcaps send fail: ret(%d)\n", ret);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int do_recv_ake_send_cert(struct hdcp_link_data *lk)
+{
+ int ret;
+ uint8_t cert[HDCP_RX_CERT_LEN + HDCP_RRX_BYTE_LEN + HDCP_CAPS_BYTE_LEN];
+
+ if (lk->is_aborted)
+ return -ECANCELED;
+
+ ret = hdcp_dplink_recv(DP_HDCP_2_2_REG_CERT_RX_OFFSET, cert,
+ sizeof(cert));
+ if (ret) {
+ hdcp_err("read cert fail. ret(%d)\n", ret);
+ return -EIO;
+ }
+
+ ret = teei_verify_cert(cert, HDCP_RX_CERT_LEN,
+ &cert[HDCP_RX_CERT_LEN], HDCP_RRX_BYTE_LEN,
+ &cert[HDCP_RX_CERT_LEN + HDCP_RRX_BYTE_LEN], HDCP_CAPS_BYTE_LEN);
+ if (ret) {
+ hdcp_err("teei_verify_cert failed (%d)\n", ret);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int do_send_ake_nostored_km(struct hdcp_link_data *lk)
+{
+ int ret;
+ uint8_t ekpub_km[HDCP_AKE_ENCKEY_BYTE_LEN];
+
+ if (lk->is_aborted)
+ return -ECANCELED;
+
+ ret = teei_generate_master_key(HDCP_LINK_TYPE_DP, ekpub_km, sizeof(ekpub_km));
+ if (ret) {
+ hdcp_err("teei_generate_master_key failed (%d)\n", ret);
+ return -EIO;
+ }
+
+ ret = hdcp_dplink_send(DP_HDCP_2_2_REG_EKPUB_KM_OFFSET, ekpub_km,
+ sizeof(ekpub_km));
+ if (ret) {
+ hdcp_err("ekpub_km send fail: ret(%d)\n", ret);
+ return -EIO;
+ }
+
+ lk->is_stored_km = false;
+ return 0;
+}
+
+static int do_send_ake_restore_km(struct hdcp_link_data *lk)
+{
+ int ret;
+ uint8_t ekh_mkey[HDCP_AKE_EKH_MKEY_BYTE_LEN];
+ uint8_t m[HDCP_AKE_M_BYTE_LEN];
+ int found_km;
+
+ if (lk->is_aborted)
+ return -ECANCELED;
+
+ ret = teei_get_pairing_info(ekh_mkey, HDCP_AKE_EKH_MKEY_BYTE_LEN,
+ m, HDCP_AKE_M_BYTE_LEN, &found_km);
+ if (ret) {
+ hdcp_err("teei_get_pairing_info failed (%d)\n", ret);
+ return -EIO;
+ }
+ if (!found_km) {
+ hdcp_info("master key is not stored\n");
+ return do_send_ake_nostored_km(lk);
+ }
+
+ ret = hdcp_dplink_send(DP_HDCP_2_2_REG_EKH_KM_WR_OFFSET, ekh_mkey,
+ HDCP_AKE_EKH_MKEY_BYTE_LEN);
+ if (ret) {
+ hdcp_err("ekh_km send fail: ret(%d)\n", ret);
+ return -EIO;
+ }
+
+ ret = hdcp_dplink_send(DP_HDCP_2_2_REG_M_OFFSET, m,
+ HDCP_AKE_M_BYTE_LEN);
+ if (ret) {
+ hdcp_err("msg_m send fail: ret(%d)\n", ret);
+ return -EIO;
+ }
+
+ lk->is_stored_km = true;
+ return 0;
+}
+
+static int check_h_prime_ready(struct hdcp_link_data *lk)
+{
+ int i = 0;
+ int ret;
+ uint8_t status = 0;
+
+ if (lk->is_aborted)
+ return -ECANCELED;
+
+ msleep(110);
+
+ /* HDCP spec is 1 sec. but we give margin 110ms */
+ while (i < 10) {
+ /* check abort state firstly,
+ * if session is abored by Rx, Tx stops Authentication process
+ */
+ if (lk->is_aborted)
+ return -ECANCELED;
+
+ /* received from CP_IRQ */
+ if (lk->hprime_ready) {
+ /* reset flag */
+ lk->hprime_ready = 0;
+ return 0;
+ }
+
+ /* check as polling mode */
+ ret = hdcp_dplink_recv(DP_HDCP_2_2_REG_RXSTATUS_OFFSET, &status,
+ sizeof(uint8_t));
+ hdcp_info("RxStatus: %x\n", status);
+
+ if (ret == 0 && HDCP_2_2_DP_RXSTATUS_H_PRIME(status)) {
+ /* reset flag */
+ lk->hprime_ready = 0;
+ return 0;
+ }
+
+ msleep(110);
+ i++;
+ }
+
+ hdcp_err("hprime timeout(%dms)\n", (110 * i));
+ return -EIO;
+}
+
+static int do_recv_ake_send_h_prime(struct hdcp_link_data *lk)
+{
+ int ret;
+ uint8_t hprime[HDCP_HMAC_SHA256_LEN];
+
+ if (lk->is_aborted)
+ return -ECANCELED;
+
+ ret = hdcp_dplink_recv(DP_HDCP_2_2_REG_HPRIME_OFFSET, hprime,
+ sizeof(hprime));
+ if (ret) {
+ hdcp_err("send_h_prime recv fail: ret(%d)\n", ret);
+ return -EIO;
+ }
+
+ ret = teei_compare_ake_hmac(hprime, HDCP_HMAC_SHA256_LEN);
+ if (ret) {
+ hdcp_err("teei_compare_ake_hmac failed (%d)\n", ret);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int check_pairing_ready(struct hdcp_link_data *lk)
+{
+ int i = 0;
+ int ret;
+ uint8_t status = 0;
+
+ if (lk->is_aborted)
+ return -ECANCELED;
+
+ msleep(220);
+ /* HDCP spec is 200ms. but we give margin 110ms */
+ while (i < 2) {
+ /* check abort state firstly,
+ * if session is abored by Rx, Tx stops Authentication process
+ */
+ if (lk->is_aborted)
+ return -ECANCELED;
+
+ /* received from CP_IRQ */
+ if (lk->pairing_ready) {
+ /* reset flag */
+ lk->pairing_ready = 0;
+ return 0;
+ }
+
+ /* check as polling mode */
+ ret = hdcp_dplink_recv(DP_HDCP_2_2_REG_RXSTATUS_OFFSET, &status,
+ sizeof(uint8_t));
+ hdcp_info("RxStatus: %x\n", status);
+
+ if (ret == 0 && HDCP_2_2_DP_RXSTATUS_PAIRING(status)) {
+ /* reset flag */
+ lk->pairing_ready = 0;
+ return 0;
+ }
+
+ msleep(110);
+ i++;
+ }
+
+ hdcp_err("pairing timeout(%dms)\n", (110 * i));
+ return -EIO;
+}
+
+static int do_recv_ake_send_pairing_info(struct hdcp_link_data *lk)
+{
+ int ret;
+ uint8_t ekh_km[HDCP_AKE_EKH_MKEY_BYTE_LEN];
+
+ if (lk->is_aborted)
+ return -ECANCELED;
+
+ ret = hdcp_dplink_recv(DP_HDCP_2_2_REG_EKH_KM_RD_OFFSET,
+ ekh_km, sizeof(ekh_km));
+ if (ret) {
+ hdcp_err("ake_send_pairing_info recv fail: ret(%d)\n", ret);
+ return -EIO;
+ }
+
+ ret = teei_set_pairing_info(ekh_km, sizeof(ekh_km));
+ if (ret) {
+ hdcp_err("teei_set_pairing_info failed (%d)\n", ret);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int auth22_exchange_master_key(struct hdcp_link_data *lk)
+{
+ /* send Tx -> Rx: AKE_init */
+ if (do_send_ake_init(lk) < 0) {
+ hdcp_err("send_ake_int fail\n");
+ return -EIO;
+ }
+
+ /* HDCP spec defined 110ms as min delay after write AKE_Init */
+ msleep(110);
+
+ /* recv Rx->Tx: AKE_Send_Cert message */
+ if (do_recv_ake_send_cert(lk) < 0) {
+ hdcp_err("recv_ake_send_cert fail\n");
+ return -EIO;
+ }
+
+ if (do_send_ake_restore_km(lk) < 0) {
+ hdcp_err("send_ake_restore_km fail\n");
+ return -EIO;
+ }
+
+ if (check_h_prime_ready(lk) < 0) {
+ hdcp_err("Cannot read H prime\n");
+ return -EIO;
+ }
+
+ /* recv Rx->Tx: AKE_Send_H_Prime message */
+ if (do_recv_ake_send_h_prime(lk) < 0) {
+ hdcp_err("recv_ake_send_h_prime fail\n");
+ return -EIO;
+ }
+
+ if (lk->is_stored_km) {
+ return 0;
+ }
+
+ if (check_pairing_ready(lk) < 0) {
+ hdcp_err("Cannot read pairing info\n");
+ return -EIO;
+ }
+
+ /* recv Rx->Tx: AKE_Send_Pairing_Info message */
+ if (do_recv_ake_send_pairing_info(lk) < 0) {
+ hdcp_err("recv_ake_send_h_prime fail\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
diff --git a/auth22-internal.h b/auth22-internal.h
new file mode 100644
index 0000000..80d95a7
--- /dev/null
+++ b/auth22-internal.h
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Samsung DisplayPort driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __EXYNOS_HDCP2_AUTH_INTERNAL_H__
+#define __EXYNOS_HDCP2_AUTH_INTERNAL_H__
+
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/mutex.h>
+#include <linux/module.h>
+
+#define HDCP_LINK_TYPE_DP 1
+
+static char *hdcp_link_st_str[] = {
+ "ST_INIT",
+ "ST_H0_NO_RX_ATTACHED",
+ "ST_H1_TX_LOW_VALUE_CONTENT",
+ "ST_A0_DETERMINE_RX_HDCP_CAP",
+ "ST_A1_EXCHANGE_MASTER_KEY",
+ "ST_A2_LOCALITY_CHECK",
+ "ST_A3_EXCHANGE_SESSION_KEY",
+ "ST_A4_TEST_REPEATER",
+ "ST_A5_AUTHENTICATED",
+ "ST_A6_WAIT_RECEIVER_ID_LIST",
+ "ST_A7_VERIFY_RECEIVER_ID_LIST",
+ "ST_A8_SEND_RECEIVER_ID_LIST_ACK",
+ "ST_A9_CONTENT_STREAM_MGT",
+ "ST_END",
+ NULL
+};
+
+typedef enum hdcp_tx_hdcp_link_state {
+ LINK_ST_INIT = 0,
+ LINK_ST_H0_NO_RX_ATTACHED,
+ LINK_ST_H1_TX_LOW_VALUE_CONTENT,
+ LINK_ST_A0_DETERMINE_RX_HDCP_CAP,
+ LINK_ST_A1_EXCHANGE_MASTER_KEY,
+ LINK_ST_A2_LOCALITY_CHECK,
+ LINK_ST_A3_EXCHANGE_SESSION_KEY,
+ LINK_ST_A4_TEST_REPEATER,
+ LINK_ST_A5_AUTHENTICATED,
+ LINK_ST_A6_WAIT_RECEIVER_ID_LIST,
+ LINK_ST_A7_VERIFY_RECEIVER_ID_LIST,
+ LINK_ST_A8_SEND_RECEIVER_ID_LIST_ACK,
+ LINK_ST_A9_CONTENT_STREAM_MGT,
+ LINK_ST_END
+} hdcp_tx_hdcp_link_state;
+
+#define UPDATE_LINK_STATE(link, st) do { \
+ hdcp_info("HDCP Link: %s -> %s\n", hdcp_link_st_str[link->state], hdcp_link_st_str[st]); \
+ link->state = st; \
+ } while (0)
+
+struct hdcp_link_data {
+ uint32_t state;
+ bool is_repeater;
+ bool is_aborted;
+ bool is_stored_km;
+ bool pairing_ready;
+ bool hprime_ready;
+ bool rp_ready;
+};
+
+int auth22_exchange_master_key(struct hdcp_link_data *lk);
+int auth22_locality_check(struct hdcp_link_data *lk);
+int auth22_exchange_session_key(struct hdcp_link_data *lk);
+int auth22_wait_for_receiver_id_list(struct hdcp_link_data *lk);
+int auth22_verify_receiver_id_list(struct hdcp_link_data *lk);
+int auth22_stream_manage(struct hdcp_link_data *lk);
+
+#endif
diff --git a/auth22-lc.c b/auth22-lc.c
new file mode 100644
index 0000000..772abaa
--- /dev/null
+++ b/auth22-lc.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Samsung DisplayPort driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <drm/drm_dp_helper.h>
+#include <linux/kernel.h>
+
+#include "auth22-internal.h"
+#include "dpcd.h"
+#include "teeif.h"
+#include "hdcp-log.h"
+
+#define MAX_LC_RETRY 10
+
+static int do_send_lc_init(struct hdcp_link_data *lk)
+{
+ int ret;
+ uint8_t rn[HDCP_RTX_BYTE_LEN];
+
+ if (lk->is_aborted)
+ return -ECANCELED;
+
+ ret = teei_gen_rn(rn, sizeof(rn));
+ if (ret) {
+ hdcp_err("teei_gen_rn failed (%d)\n", ret);
+ return -EIO;
+ }
+
+ ret = hdcp_dplink_send(DP_HDCP_2_2_REG_RN_OFFSET, rn, sizeof(rn));
+ if (ret) {
+ hdcp_err("rn send fail: ret(%d)\n", ret);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int do_recv_lc_send_l_prime(struct hdcp_link_data *lk)
+{
+ int ret;
+ uint8_t lprime[HDCP_HMAC_SHA256_LEN];
+
+ if (lk->is_aborted)
+ return -ECANCELED;
+
+ ret = hdcp_dplink_recv(DP_HDCP_2_2_REG_LPRIME_OFFSET, lprime,
+ sizeof(lprime));
+ if (ret) {
+ hdcp_err("l_prime recv fail. ret(%d)\n", ret);
+ return -EIO;
+ }
+
+ ret = teei_compare_lc_hmac(lprime, sizeof(lprime));
+ if (ret) {
+ hdcp_err("teei_compare_lc_hmac failed (%d).\n", ret);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int auth22_locality_check(struct hdcp_link_data *lk)
+{
+ int i;
+
+ for (i = 0; i < MAX_LC_RETRY; i++) {
+ /* send Tx -> Rx: LC_init */
+ if (do_send_lc_init(lk) < 0) {
+ hdcp_err("send_lc_init fail\n");
+ return -EIO;
+ }
+
+ /* wait until max dealy */
+ msleep(16);
+
+ /* recv Rx -> Tx: LC_Send_L_Prime */
+ if (do_recv_lc_send_l_prime(lk) < 0) {
+ hdcp_err("recv_lc_send_l_prime fail\n");
+ /* retry */
+ continue;
+ } else {
+ hdcp_debug("LC success. retryed(%d)\n", i);
+ break;
+ }
+ }
+
+ if (i == MAX_LC_RETRY) {
+ hdcp_err("LC check fail. exceed retry count(%d)\n", i);
+ return -EFAULT;
+ }
+
+ return 0;
+}
diff --git a/auth22-repeater.c b/auth22-repeater.c
new file mode 100644
index 0000000..c31478e
--- /dev/null
+++ b/auth22-repeater.c
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Samsung DisplayPort driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <drm/drm_dp_helper.h>
+#include <linux/in.h>
+#include <linux/kernel.h>
+
+#include "auth22-internal.h"
+#include "dpcd.h"
+#include "teeif.h"
+#include "hdcp-log.h"
+
+#define DEV_COUNT_SHIFT (4)
+#define DEV_COUNT_MASK (0x1F)
+
+static int cal_rcvid_list_size(uint8_t *rxinfo)
+{
+ uint8_t dev_count;
+ uint16_t rxinfo_val;
+
+ memcpy((uint8_t *)&rxinfo_val, rxinfo, sizeof(rxinfo_val));
+ rxinfo_val = htons(rxinfo_val);
+ dev_count = (rxinfo_val >> DEV_COUNT_SHIFT) & DEV_COUNT_MASK;
+ return HDCP_RCV_ID_LEN * dev_count;
+}
+
+int auth22_wait_for_receiver_id_list(struct hdcp_link_data *lk)
+{
+ int i = 0;
+ int ret;
+ uint8_t status = 0;
+
+ /* HDCP spec is 5 sec */
+ while (i < 50) {
+ /* check abort state firstly,
+ * if session is abored by Rx, Tx stops Authentication process
+ */
+ if (lk->is_aborted)
+ return -ECANCELED;
+
+ /* received from CP_IRQ */
+ if (lk->rp_ready) {
+ /* reset flag */
+ lk->rp_ready = 0;
+ return 0;
+ }
+
+ /* check as polling mode */
+ ret = hdcp_dplink_recv(DP_HDCP_2_2_REG_RXSTATUS_OFFSET, &status,
+ sizeof(uint8_t));
+ hdcp_info("RxStatus: %x\n", status);
+
+ if (ret == 0 && HDCP_2_2_DP_RXSTATUS_READY(status)) {
+ /* reset flag */
+ lk->rp_ready = 0;
+ return 0;
+ }
+
+ msleep(110);
+ i++;
+ }
+
+ hdcp_err("receiver ID list timeout(%dms)\n", (110 * i));
+ return -ETIMEDOUT;
+}
+
+int auth22_verify_receiver_id_list(struct hdcp_link_data *lk) {
+ int ret;
+ uint8_t rx_info[HDCP_RP_RX_INFO_LEN];
+ uint8_t seq_num_v[HDCP_RP_SEQ_NUM_V_LEN];
+ uint8_t v_prime[HDCP_RP_HMAC_V_LEN / 2];
+ uint8_t rcvid_list[HDCP_RP_RCVID_LIST_LEN];
+ uint8_t v[HDCP_RP_HMAC_V_LEN / 2];
+ uint8_t valid;
+
+ if (lk->is_aborted)
+ return -ECANCELED;
+
+ ret = hdcp_dplink_recv(DP_HDCP_2_2_REG_RXINFO_OFFSET, rx_info,
+ sizeof(rx_info));
+ if (ret) {
+ hdcp_err("rx_info rcv fail: ret(%d)\n", ret);
+ return -EIO;
+ }
+
+ ret = hdcp_dplink_recv(DP_HDCP_2_2_REG_SEQ_NUM_V_OFFSET, seq_num_v,
+ sizeof(seq_num_v));
+ if (ret) {
+ hdcp_err("seq_num_v rcv fail: ret(%d)\n", ret);
+ return -EIO;
+ }
+
+ ret = hdcp_dplink_recv(DP_HDCP_2_2_REG_VPRIME_OFFSET, v_prime,
+ sizeof(v_prime));
+ if (ret) {
+ hdcp_err("v_prime rcv fail: ret(%d)\n", ret);
+ return -EIO;
+ }
+
+ ret = hdcp_dplink_recv(DP_HDCP_2_2_REG_RECV_ID_LIST_OFFSET, rcvid_list,
+ cal_rcvid_list_size(rx_info));
+ if (ret) {
+ hdcp_err("rcvid_list rcv fail: ret(%d)\n", ret);
+ return -EIO;
+ }
+
+ /* set receiver id list */
+ ret = teei_set_rcvlist_info(rx_info, seq_num_v, v_prime, rcvid_list,
+ v, &valid);
+ if (ret) {
+ hdcp_err("teei_set_rcvid_list() failed %d\n", ret);
+ return -EIO;
+ }
+
+ if (valid == 0) {
+ hdcp_err("vprime verification failed\n");
+ return -EIO;
+ }
+
+ ret = hdcp_dplink_send(DP_HDCP_2_2_REG_V_OFFSET, v,
+ HDCP_RP_HMAC_V_LEN / 2);
+ if (ret) {
+ hdcp_err("V send fail: ret(%d)\n", ret);
+ return -EIO;
+ }
+
+ return 0;
+}
diff --git a/auth22-ske.c b/auth22-ske.c
new file mode 100644
index 0000000..e75d96d
--- /dev/null
+++ b/auth22-ske.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Samsung DisplayPort driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <drm/drm_dp_helper.h>
+#include <linux/kernel.h>
+
+#include "auth22-internal.h"
+#include "dpcd.h"
+#include "teeif.h"
+#include "hdcp-log.h"
+
+static int do_send_ske_send_eks(struct hdcp_link_data *lk)
+{
+ int ret;
+ uint8_t type = 0x00;
+ uint8_t edkey_ks[HDCP_AKE_MKEY_BYTE_LEN];
+ uint8_t riv[HDCP_RTX_BYTE_LEN];
+
+ if (lk->is_aborted)
+ return -ECANCELED;
+
+ ret = teei_generate_riv(riv, sizeof(riv));
+ if (ret) {
+ hdcp_err("teei_generate_riv failed (%d)\n", ret);
+ return -EIO;
+ }
+
+ ret = teei_generate_skey(HDCP_LINK_TYPE_DP, edkey_ks,
+ HDCP_SKE_SKEY_LEN, 0);
+ if (ret) {
+ hdcp_err("teei_generate_skey failed (%d)\n", ret);
+ return -EIO;
+ }
+
+ ret = hdcp_dplink_send(DP_HDCP_2_2_REG_EDKEY_KS_OFFSET, edkey_ks,
+ HDCP_AKE_MKEY_BYTE_LEN);
+ if (ret) {
+ hdcp_err("edkey_ks send fail. ret(%d)\n", ret);
+ return -EIO;
+ }
+
+ ret = hdcp_dplink_send(DP_HDCP_2_2_REG_RIV_OFFSET, riv, sizeof(riv));
+ if (ret) {
+ hdcp_err("riv send fail. ret(%x)\n", ret);
+ return -EIO;
+ }
+
+ if (lk->is_repeater)
+ return 0;
+
+ ret = hdcp_dplink_send(DP_HDCP_2_2_REG_STREAM_TYPE_OFFSET, &type,
+ sizeof(type));
+ if (ret) {
+ hdcp_err("type send fail: %x\n", ret);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int auth22_exchange_session_key(struct hdcp_link_data *lk)
+{
+ /* Send Tx -> Rx: SKE_Send_Eks */
+ if (do_send_ske_send_eks(lk) < 0) {
+ hdcp_err("send_ske_send_eks fail\n");
+ return -EIO;
+ }
+
+ return 0;
+}
diff --git a/auth22-stream.c b/auth22-stream.c
new file mode 100644
index 0000000..375b398
--- /dev/null
+++ b/auth22-stream.c
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Samsung DisplayPort driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <drm/drm_dp_helper.h>
+#include <linux/kernel.h>
+
+#include "auth22-internal.h"
+#include "dpcd.h"
+#include "teeif.h"
+#include "hdcp-log.h"
+
+#define HDCP_DP_STREAM_NUM 1
+
+static int do_send_rp_stream_manage(struct hdcp_link_data *lk)
+{
+ int ret;
+ uint16_t stream_num = HDCP_DP_STREAM_NUM;
+ uint8_t strm_id[HDCP_RP_MAX_STREAMID_NUM] = {0x0};
+ uint8_t seq_num_m[HDCP_RP_SEQ_NUM_M_LEN];
+ uint8_t k[HDCP_RP_K_LEN];
+ uint8_t streamid_type[HDCP_RP_MAX_STREAMID_TYPE_LEN];
+
+ if (lk->is_aborted)
+ return -ECANCELED;
+
+ /* set receiver id list */
+ ret = teei_gen_stream_manage(stream_num, strm_id,
+ seq_num_m, k, streamid_type);
+ if (ret) {
+ hdcp_err("teei_gen_stream_manage() failed %d\n", ret);
+ return -EIO;
+ }
+
+ ret = hdcp_dplink_send(DP_HDCP_2_2_REG_SEQ_NUM_M_OFFSET, seq_num_m,
+ sizeof(seq_num_m));
+ if (ret) {
+ hdcp_err("seq_num_M send fail. ret(%d)\n", ret);
+ return -EIO;
+ }
+
+ ret = hdcp_dplink_send(DP_HDCP_2_2_REG_K_OFFSET, k, sizeof(k));
+ if (ret) {
+ hdcp_err("k send fail. ret(%x)\n", ret);
+ return -EIO;
+ }
+
+ ret = hdcp_dplink_send(DP_HDCP_2_2_REG_STREAM_ID_TYPE_OFFSET,
+ streamid_type, stream_num * HDCP_RP_STREAMID_TYPE_LEN);
+ if (ret) {
+ hdcp_err("Streamid_Type send fail. ret(%x)\n", ret);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int do_recv_rp_stream_ready(struct hdcp_link_data *lk)
+{
+ int ret;
+ uint8_t m_prime[HDCP_RP_HMAC_M_LEN];
+
+ if (lk->is_aborted)
+ return -ECANCELED;
+
+ ret = hdcp_dplink_recv(DP_HDCP_2_2_REG_MPRIME_OFFSET, m_prime,
+ sizeof(m_prime));
+ if (ret) {
+ hdcp_err("M' recv fail. ret(%d)\n", ret);
+ return -EIO;
+ }
+
+ ret = teei_verify_m_prime(m_prime, NULL, 0);
+ if (ret) {
+ hdcp_err("teei_verify_m_prime failed %d\n", ret);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+int auth22_stream_manage(struct hdcp_link_data *lk)
+{
+ /* Send Tx -> Rx: RepeaterAuth_Stream_Manage */
+ if (do_send_rp_stream_manage(lk) < 0) {
+ hdcp_err("send_rp_stream_manage fail\n");
+ return -EIO;
+ }
+
+ /* HDCP spec define 110ms as min delay. But we give 110ms margin */
+ msleep(220);
+
+ /* recv Rx->Tx: RepeaterAuth_Stream_Ready message */
+ if (do_recv_rp_stream_ready(lk) < 0) {
+ hdcp_err("recv_rp_stream_ready fail\n");
+ return -EIO;
+ }
+
+ return 0;
+}
diff --git a/auth22.c b/auth22.c
new file mode 100644
index 0000000..0b54ed9
--- /dev/null
+++ b/auth22.c
@@ -0,0 +1,194 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Samsung DisplayPort driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/smc.h>
+#include <asm/cacheflush.h>
+#include <linux/soc/samsung/exynos-smc.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <drm/drm_dp_helper.h>
+
+#include "exynos-hdcp-interface.h"
+
+#include "auth-control.h"
+#include "auth22.h"
+#include "auth22-internal.h"
+#include "dpcd.h"
+#include "hdcp-log.h"
+#include "teeif.h"
+
+#define RECVID_WAIT_RETRY_COUNT (5)
+#define DP_RXCAPS_HDCP_CAPABLE (0x1 << 1)
+#define DP_RXCAPS_REPEATER (0x1 << 0)
+#define DP_RXCAPS_HDCP_VERSION_2 (0x2)
+
+static struct hdcp_link_data lkd;
+
+static int auth22_determine_rx_hdcp_cap(struct hdcp_link_data *lk)
+{
+ int ret;
+ uint8_t rxcaps[HDCP_CAPS_BYTE_LEN];
+
+ ret = hdcp_dplink_recv(DP_HDCP_2_2_REG_RX_CAPS_OFFSET, rxcaps,
+ sizeof(rxcaps));
+ if (ret) {
+ hdcp_err("check rx caps recv fail: ret(%d)\n", ret);
+ return -EIO;
+ }
+
+ if (!(rxcaps[2] & DP_RXCAPS_HDCP_CAPABLE)) {
+ hdcp_err("RX is not HDCP capable. rxcaps(0x%02x%02x%02x)\n",
+ rxcaps[0], rxcaps[1], rxcaps[2]);
+ return -EIO;
+ }
+
+ if (rxcaps[0] != DP_RXCAPS_HDCP_VERSION_2) {
+ hdcp_err("RX does not support V2. rxcaps(0x%02x%02x%02x)\n",
+ rxcaps[0], rxcaps[1], rxcaps[2]);
+ return -EIO;
+ }
+
+ lk->is_repeater = rxcaps[2] & DP_RXCAPS_REPEATER;
+ return 0;
+}
+
+int hdcp22_dplink_authenticate(void)
+{
+ struct hdcp_link_data *lk_data = &lkd;
+ bool rp_ready = lk_data->rp_ready;
+
+ memset(&lkd, 0, sizeof(lkd));
+ if (rp_ready)
+ UPDATE_LINK_STATE(lk_data, LINK_ST_A7_VERIFY_RECEIVER_ID_LIST);
+ else
+ UPDATE_LINK_STATE(lk_data, LINK_ST_A0_DETERMINE_RX_HDCP_CAP);
+
+ do {
+ switch (lk_data->state) {
+ case LINK_ST_H1_TX_LOW_VALUE_CONTENT:
+ return -EIO;
+ case LINK_ST_A0_DETERMINE_RX_HDCP_CAP:
+ if (auth22_determine_rx_hdcp_cap(lk_data) == 0) {
+ UPDATE_LINK_STATE(lk_data, LINK_ST_A1_EXCHANGE_MASTER_KEY);
+ } else {
+ UPDATE_LINK_STATE(lk_data, LINK_ST_H1_TX_LOW_VALUE_CONTENT);
+ }
+ break;
+ case LINK_ST_A1_EXCHANGE_MASTER_KEY:
+ if (auth22_exchange_master_key(lk_data) == 0) {
+ UPDATE_LINK_STATE(lk_data, LINK_ST_A2_LOCALITY_CHECK);
+ } else {
+ UPDATE_LINK_STATE(lk_data, LINK_ST_H1_TX_LOW_VALUE_CONTENT);
+ return -EAGAIN;
+ }
+ break;
+ case LINK_ST_A2_LOCALITY_CHECK:
+ if (auth22_locality_check(lk_data) == 0) {
+ UPDATE_LINK_STATE(lk_data, LINK_ST_A3_EXCHANGE_SESSION_KEY);
+ } else {
+ UPDATE_LINK_STATE(lk_data, LINK_ST_H1_TX_LOW_VALUE_CONTENT);
+ return -EAGAIN;
+ }
+ break;
+ case LINK_ST_A3_EXCHANGE_SESSION_KEY:
+ if (auth22_exchange_session_key(lk_data) == 0) {
+ UPDATE_LINK_STATE(lk_data, LINK_ST_A4_TEST_REPEATER);
+ } else {
+ UPDATE_LINK_STATE(lk_data, LINK_ST_H1_TX_LOW_VALUE_CONTENT);
+ }
+ break;
+ case LINK_ST_A4_TEST_REPEATER:
+ if (lk_data->is_repeater) {
+ /* if it is a repeater, verify Rcv ID list */
+ UPDATE_LINK_STATE(lk_data, LINK_ST_A6_WAIT_RECEIVER_ID_LIST);
+ hdcp_info("It`s repeater link !\n");
+ } else {
+ /* if it is not a repeater, complete authentication */
+ UPDATE_LINK_STATE(lk_data, LINK_ST_A5_AUTHENTICATED);
+ hdcp_info("It`s Rx link !\n");
+ }
+ break;
+ case LINK_ST_A5_AUTHENTICATED:
+ return 0;
+ case LINK_ST_A6_WAIT_RECEIVER_ID_LIST:
+ if (auth22_wait_for_receiver_id_list(lk_data) == 0) {
+ UPDATE_LINK_STATE(lk_data, LINK_ST_A7_VERIFY_RECEIVER_ID_LIST);
+ } else {
+ UPDATE_LINK_STATE(lk_data, LINK_ST_H1_TX_LOW_VALUE_CONTENT);
+ }
+ break;
+ case LINK_ST_A7_VERIFY_RECEIVER_ID_LIST:
+ if (auth22_verify_receiver_id_list(lk_data) == 0) {
+ UPDATE_LINK_STATE(lk_data, LINK_ST_A9_CONTENT_STREAM_MGT);
+ } else {
+ UPDATE_LINK_STATE(lk_data, LINK_ST_H1_TX_LOW_VALUE_CONTENT);
+ }
+ break;
+ case LINK_ST_A9_CONTENT_STREAM_MGT:
+ if (auth22_stream_manage(lk_data) == 0) {
+ UPDATE_LINK_STATE(lk_data, LINK_ST_A5_AUTHENTICATED);
+ } else {
+ UPDATE_LINK_STATE(lk_data, LINK_ST_H1_TX_LOW_VALUE_CONTENT);
+ }
+ break;
+ default:
+ UPDATE_LINK_STATE(lk_data, LINK_ST_H1_TX_LOW_VALUE_CONTENT);
+ break;
+ }
+ } while (1);
+}
+
+int hdcp22_dplink_abort(void) {
+ lkd.is_aborted = 1;
+ return 0;
+}
+
+int hdcp22_dplink_handle_irq(void) {
+ uint8_t rxstatus = 0;
+
+ /* check as polling mode */
+ int ret = hdcp_dplink_recv(DP_HDCP_2_2_REG_RXSTATUS_OFFSET, &rxstatus,
+ sizeof(uint8_t));
+ if (ret) {
+ hdcp_err("RXStatus read fail (%d)\n", ret);
+ return -EIO;
+ }
+ hdcp_info("RxStatus: %x\n", rxstatus);
+
+ if (HDCP_2_2_DP_RXSTATUS_LINK_FAILED(rxstatus)) {
+ hdcp_info("integrity check fail.\n");
+ hdcp_tee_disable_enc();
+ return 0;
+ } else if (HDCP_2_2_DP_RXSTATUS_REAUTH_REQ(rxstatus)) {
+ hdcp_info("reauth requested.\n");
+ hdcp_tee_disable_enc();
+ return -EAGAIN;
+ } else if (HDCP_2_2_DP_RXSTATUS_PAIRING(rxstatus)) {
+ hdcp_info("pairing avaible\n");
+ lkd.pairing_ready = 1;
+ return 0;
+ } else if (HDCP_2_2_DP_RXSTATUS_H_PRIME(rxstatus)) {
+ hdcp_info("h-prime avaible\n");
+ lkd.hprime_ready = 1;
+ return 0;
+ } else if (HDCP_2_2_DP_RXSTATUS_READY(rxstatus)) {
+ hdcp_info("ready avaible\n");
+ lkd.rp_ready = 1;
+ if (hdcp_get_auth_state() == HDCP2_AUTH_DONE)
+ return -EAGAIN;
+ return 0;
+ }
+
+ hdcp_err("undefined RxStatus(0x%x). ignore\n", rxstatus);
+ return -EINVAL;
+}
diff --git a/auth22.h b/auth22.h
new file mode 100644
index 0000000..a1d456b
--- /dev/null
+++ b/auth22.h
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Samsung DisplayPort driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __EXYNOS_HDCP2_AUTH_H__
+#define __EXYNOS_HDCP2_AUTH_H__
+
+int hdcp22_dplink_authenticate(void);
+int hdcp22_dplink_abort(void);
+int hdcp22_dplink_handle_irq(void);
+
+#endif
diff --git a/dpcd.c b/dpcd.c
new file mode 100644
index 0000000..0c29913
--- /dev/null
+++ b/dpcd.c
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Samsung DisplayPort driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <net/sock.h>
+#include <linux/netlink.h>
+#include <linux/skbuff.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+
+#include "exynos-hdcp-interface.h"
+
+#include "dpcd.h"
+#include "hdcp-log.h"
+
+static void (*pdp_hdcp22_enable)(u32 en);
+static int (*pdp_dpcd_read_for_hdcp22)(u32 address, u32 length, u8 *data);
+static int (*pdp_dpcd_write_for_hdcp22)(u32 address, u32 length, u8 *data);
+
+int hdcp_dplink_recv(uint32_t addr, uint8_t *data, uint32_t size)
+{
+ return pdp_dpcd_read_for_hdcp22(addr, size, data);
+}
+
+int hdcp_dplink_send(uint32_t addr, uint8_t *data, uint32_t size)
+{
+ return pdp_dpcd_write_for_hdcp22(addr, size, data);
+}
+
+void dp_register_func_for_hdcp22(void (*func0)(u32 en), int (*func1)(u32 address, u32 length, u8 *data), int (*func2)(u32 address, u32 length, u8 *data))
+{
+ pdp_hdcp22_enable = func0;
+ pdp_dpcd_read_for_hdcp22 = func1;
+ pdp_dpcd_write_for_hdcp22 = func2;
+}
+EXPORT_SYMBOL_GPL(dp_register_func_for_hdcp22);
diff --git a/dpcd.h b/dpcd.h
new file mode 100644
index 0000000..ccbdb12
--- /dev/null
+++ b/dpcd.h
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Samsung DisplayPort driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __EXYNOS_HDCP_DPCD_H__
+#define __EXYNOS_HDCP_DPCD_H__
+
+int hdcp_dplink_recv(uint32_t msg_name, uint8_t *data, uint32_t size);
+int hdcp_dplink_send(uint32_t msg_name, uint8_t *data, uint32_t size);
+
+#endif
diff --git a/exynos-hdcp-interface.h b/exynos-hdcp-interface.h
new file mode 100644
index 0000000..d68cf25
--- /dev/null
+++ b/exynos-hdcp-interface.h
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Samsung DisplayPort driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __EXYNOS_HDCP_INTERFACE_H__
+#define __EXYNOS_HDCP_INTERFACE_H__
+
+/* Displayport */
+enum dp_state {
+ DP_DISCONNECT,
+ DP_CONNECT,
+};
+
+void hdcp_dplink_connect_state(enum dp_state state);
+void hdcp_dplink_handle_irq(void);
+void dp_register_func_for_hdcp22(void (*func0)(u32 en), int (*func1)(u32 address, u32 length, u8 *data), int (*func2)(u32 address, u32 length, u8 *data));
+
+/* DEPRECATED */
+enum auth_signal {
+ HDCP_OFF,
+ HDCP1_ON,
+ HDCP2_ON,
+};
+
+int hdcp_dplink_auth_check(enum auth_signal);
+int hdcp_dplink_get_rxstatus(uint8_t *status);
+int hdcp_dplink_set_paring_available(void);
+int hdcp_dplink_set_hprime_available(void);
+int hdcp_dplink_set_rp_ready(void);
+int hdcp_dplink_set_reauth(void);
+
+#endif
diff --git a/exynos-hdcp1-auth.h b/exynos-hdcp1-auth.h
deleted file mode 100644
index e36de3f..0000000
--- a/exynos-hdcp1-auth.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * drivers/soc/samsung/exynos-hdcp/exynos-hdcp1-auth.h
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef __EXYNOS_HDCP1_AUTH_H__
-#define __EXYNOS_HDCP1_AUTH_H__
-
-void hdcp13_dplink_authenticate(void);
-
-#endif
diff --git a/exynos-hdcp2-dplink-auth.c b/exynos-hdcp2-dplink-auth.c
deleted file mode 100644
index 958a97f..0000000
--- a/exynos-hdcp2-dplink-auth.c
+++ /dev/null
@@ -1,1148 +0,0 @@
-/* drivers/soc/samsung/exynos-hdcp/dplink/exynos-hdcp2-dplink-auth.c
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-#include <linux/delay.h>
-#include <linux/module.h>
-#include "exynos-hdcp2.h"
-#include "exynos-hdcp2-log.h"
-#include "exynos-hdcp2-dplink-auth.h"
-#include "exynos-hdcp2-dplink-if.h"
-#include "exynos-hdcp2-dplink.h"
-#include "exynos-hdcp2-dplink-inter.h"
-
-#define MAX_LC_RETRY 10
-
-static uint8_t pairing_ready;
-static uint8_t hprime_ready;
-uint8_t rp_ready;
-static uint8_t rp_ready_s;
-static uint8_t reauth_req;
-static uint8_t integrity_fail;
-
-static char *hdcp_msgid_str[] = {
- NULL,
- "Null message",
- "DP_AKE_Init",
- "DP_AKE_Send_Cert",
- "DP_AKE_No_Stored_km",
- "DP_AKE_Stored_km",
- "DP_AKE_Send_rrx",
- "DP_AKE_Send_H_prime",
- "DP_AKE_Send_Pairing_Info",
- "DP_LC_Init",
- "DP_LC_Send_L_prime",
- "DP_SKE_Send_Eks",
- "DP_RepeaterAuth_Send_ReceiverID_List",
- "DP_RTT_Ready",
- "DP_RTT_Challenge",
- "DP_RepeaterAuth_Send_Ack",
- "DP_RepeaterAuth_Stream_Manage",
- "DP_RepeaterAuth_Stream_Ready",
- "DP_Receiver_AuthStatus",
- "DP_AKE_Transmitter_Info",
- "DPAKE_Receiver_Info",
- NULL
-};
-
-struct dp_ake_init {
- uint8_t rtx[HDCP_AKE_RTX_BYTE_LEN];
- uint8_t txcaps[HDCP_CAPS_BYTE_LEN];
-};
-
-struct dp_ake_send_cert {
- uint8_t cert_rx[HDCP_RX_CERT_LEN];
- uint8_t rrx[HDCP_RRX_BYTE_LEN];
- uint8_t rxcaps[HDCP_CAPS_BYTE_LEN];
-};
-
-struct dp_ake_no_stored_km {
- uint8_t ekpub_km[HDCP_AKE_ENCKEY_BYTE_LEN];
-};
-
-struct dp_ake_stored_km {
- uint8_t ekh_km[HDCP_AKE_EKH_MKEY_BYTE_LEN];
- uint8_t m[HDCP_AKE_M_BYTE_LEN];
-};
-
-struct dp_ake_send_h_prime {
- uint8_t h_prime[HDCP_HMAC_SHA256_LEN];
-};
-
-struct dp_ake_send_pairing_info {
- uint8_t ekh_km[HDCP_AKE_MKEY_BYTE_LEN];
-};
-
-struct dp_lc_init {
- uint8_t rn[HDCP_RTX_BYTE_LEN];
-};
-
-struct dp_lc_send_l_prime {
- uint8_t l_prime[HDCP_HMAC_SHA256_LEN];
-};
-
-struct dp_ske_send_eks {
- uint8_t edkey_ks[HDCP_AKE_MKEY_BYTE_LEN];
- uint8_t riv[HDCP_RTX_BYTE_LEN];
-};
-
-struct dp_rp_send_rcvid_list {
- uint8_t rx_info[HDCP_RP_RX_INFO_LEN];
- uint8_t seq_num_v[HDCP_RP_SEQ_NUM_V_LEN];
- uint8_t v_prime[HDCP_RP_HMAC_V_LEN / 2];
- uint8_t rcvid_list[HDCP_RP_RCVID_LIST_LEN];
-};
-
-struct dp_rp_send_ack {
- uint8_t v[HDCP_RP_HMAC_V_LEN / 2];
-};
-
-struct dp_rp_stream_manage {
- uint8_t seq_num_m[HDCP_RP_SEQ_NUM_M_LEN];
- uint8_t k[HDCP_RP_K_LEN];
- uint8_t streamid_type[HDCP_RP_MAX_STREAMID_TYPE_LEN];
-};
-
-struct dp_rp_stream_ready {
- uint8_t m_prime[HDCP_RP_HMAC_M_LEN];
-};
-
-struct rxinfo {
- uint8_t depth;
- uint8_t dev_count;
- uint8_t max_dev_exd;
- uint8_t max_cascade_exd;
- uint8_t hdcp20_downstream;
- uint8_t hdcp1x_downstream;
-};
-
-static uint16_t dp_htons(uint16_t x)
-{
- return (
- ((x & 0x00FF) << 8) |
- ((x & 0xFF00) >> 8)
- );
-}
-
-static void rxinfo_convert_arr2st(uint8_t *arr, struct rxinfo *st)
-{
- uint16_t rxinfo_val;
-
- memcpy((uint8_t *)&rxinfo_val, arr, sizeof(rxinfo_val));
- /* convert to little endian */
- rxinfo_val = dp_htons(rxinfo_val);
-
- st->depth = (rxinfo_val >> DEPTH_SHIFT) & DEPTH_MASK;
- st->dev_count = (rxinfo_val >> DEV_COUNT_SHIFT) & DEV_COUNT_MASK;
- st->max_dev_exd = (rxinfo_val >> DEV_EXD_SHIFT) & DEV_EXD_MASK;
- st->max_cascade_exd = (rxinfo_val >> CASCADE_EXD_SHIFT) & CASCADE_EXD_MASK;
- st->hdcp20_downstream = (rxinfo_val >> HDCP20_DOWN_SHIFT) & HDCP20_DOWN_MASK;
- st->hdcp1x_downstream = (rxinfo_val >> HDCP1X_DOWN_SHIFT) & HDCP1X_DOWN_MASK;
-}
-
-static int is_auth_aborted(void)
-{
- /* todo: need mutex */
- if (integrity_fail || reauth_req) {
- /* clear flag */
- dplink_clear_irqflag_all();
- hdcp_err("Authentication is aborted\n");
- return 1;
- }
-
- return 0;
-}
-
-static int dp_send_protocol_msg(struct hdcp_link_data *lk, uint8_t msg_id, struct hdcp_msg_info *msg_info)
-{
- int ret = TX_AUTH_SUCCESS;
-
- hdcp_info("Tx->Rx: %s\n", hdcp_msgid_str[msg_id]);
- ret = dp_cap_protocol_msg(msg_id,
- msg_info->msg,
- (size_t *)&msg_info->msg_len,
- &lk->tx_ctx,
- &lk->rx_ctx);
- if (ret) {
- hdcp_err("dp_cap_protocol_msg() failed. ret(0x%08x)\n", ret);
- return -TX_AUTH_ERROR_MAKE_PROTO_MSG;
- }
-
- return TX_AUTH_SUCCESS;
-}
-
-static int dp_recv_protocol_msg(struct hdcp_link_data *lk, uint8_t msg_id, struct hdcp_msg_info *msg_info)
-{
- int ret = TX_AUTH_SUCCESS;
-
- if (msg_info->msg_len > 0) {
- /* parsing received message */
- ret = dp_decap_protocol_msg(msg_id,
- msg_info->msg,
- msg_info->msg_len,
- &lk->tx_ctx,
- &lk->rx_ctx);
- if (ret) {
- hdcp_err("dp_decap_protocol_msg() failed. msg_id(%d), ret(0x%08x)\n", msg_id, ret);
- ret = -TX_AUTH_ERROR_WRONG_MSG;
- }
- }
-
- hdcp_info("Rx->Tx: %s\n", hdcp_msgid_str[msg_id]);
-
- return ret;
-}
-
-static int dp_ake_find_masterkey(int *found)
-{
- int ret = TX_AUTH_SUCCESS;
- uint8_t ekh_mkey[HDCP_AKE_EKH_MKEY_BYTE_LEN] = {0};
- uint8_t m[HDCP_AKE_M_BYTE_LEN] = {0};
-
- ret = ake_find_masterkey(found,
- ekh_mkey, HDCP_AKE_EKH_MKEY_BYTE_LEN,
- m, HDCP_AKE_M_BYTE_LEN);
- if (ret) {
- hdcp_err("fail to find stored km: ret(%d)\n", ret);
- return -1;
- }
-
- return 0;
-}
-
-static int dp_get_hdcp_session_key(struct hdcp_link_data *lk)
-{
- return 0;
-}
-
-static int dp_put_hdcp_session_key(struct hdcp_link_data *lk)
-{
- return 0;
-}
-
-static int do_send_ake_init(struct hdcp_link_data *lk)
-{
- int ret;
- struct hdcp_msg_info msg_info;
- struct dp_ake_init *m_init;
-
- /* check abort state firstly,
- * if session is abored by Rx, Tx stops Authentication process
- */
- if (is_auth_aborted())
- return -TX_AUTH_ERROR_ABORT;
-
- ret = dp_send_protocol_msg(lk, DP_AKE_INIT, &msg_info);
- if (ret < 0) {
- hdcp_err("AKE_Init failed: ret(%d)\n", ret);
- return -1;
- }
-
- m_init = (struct dp_ake_init *)msg_info.msg;
- ret = hdcp_dplink_send(HDCP22_MSG_RTX_W,
- m_init->rtx,
- sizeof(m_init->rtx));
- if (ret) {
- hdcp_err("rtx send fail: ret(%d)\n", ret);
- return -1;
- }
-
- ret = hdcp_dplink_send(HDCP22_MSG_TXCAPS_W,
- m_init->txcaps,
- sizeof(m_init->txcaps));
- if (ret) {
- hdcp_err("txcaps send fail: ret(%d)\n", ret);
- return -1;
- }
-
- return 0;
-}
-
-static void parse_rxcaps_info(uint8_t *rxcaps, struct hdcp_link_data *lk)
-{
- memcpy(lk->rx_ctx.caps, rxcaps, sizeof(lk->rx_ctx.caps));
- if (rxcaps[2] & DP_RXCAPS_REPEATER) {
- hdcp_info("Rx is Repeater. rxcaps(0x%02x%02x%02x)\n",
- rxcaps[0], rxcaps[1], rxcaps[2]);
- lk->rx_ctx.repeater = 1;
- } else {
- hdcp_info("Rx is NOT Repeater. rxcaps(0x%02x%02x%02x)\n",
- rxcaps[0], rxcaps[1], rxcaps[2]);
- lk->rx_ctx.repeater = 0;
- }
-}
-
-static int do_recv_ake_send_cert(struct hdcp_link_data *lk)
-{
- int ret;
- struct hdcp_msg_info msg_info;
- struct dp_ake_send_cert m_send_cert;
-
- /* check abort state firstly,
- * if session is abored by Rx, Tx stops Authentication process
- */
- if (is_auth_aborted())
- return -TX_AUTH_ERROR_ABORT;
-
- ret = hdcp_dplink_recv(HDCP22_MSG_CERT_RX_R,
- m_send_cert.cert_rx,
- HDCP_RX_CERT_LEN + HDCP_RRX_BYTE_LEN + HDCP_CAPS_BYTE_LEN);
- if (ret) {
- hdcp_err("ake_send_cert cert recv fail. ret(%d)\n", ret);
- return -1;
- }
-
- parse_rxcaps_info(m_send_cert.rxcaps, lk);
-
- memcpy(msg_info.msg, &m_send_cert, sizeof(struct dp_ake_send_cert));
- msg_info.msg_len = sizeof(struct dp_ake_send_cert);
- ret = dp_recv_protocol_msg(lk, DP_AKE_SEND_CERT, &msg_info);
- if (ret < 0) {
- hdcp_err("recv AKE_Send_Cert failed\n");
- return -1;
- }
-
- return 0;
-}
-
-static int do_send_ake_nostored_km(struct hdcp_link_data *lk)
-{
- int ret;
- struct hdcp_msg_info msg_info;
- struct dp_ake_no_stored_km *m_nostored_km;
-
- /* check abort state firstly,
- * if session is abored by Rx, Tx stops Authentication process
- */
- if (is_auth_aborted())
- return -TX_AUTH_ERROR_ABORT;
-
- ret = dp_send_protocol_msg(lk, DP_AKE_NO_STORED_KM, &msg_info);
- if (ret < 0) {
- hdcp_err("send AKE_No_Stored_km failed. ret(%d)\n", ret);
- return -1;
- }
-
- m_nostored_km = (struct dp_ake_no_stored_km *)msg_info.msg;
- ret = hdcp_dplink_send(HDCP22_MSG_EKPUB_KM_W,
- m_nostored_km->ekpub_km,
- sizeof(m_nostored_km->ekpub_km));
- if (ret) {
- hdcp_err("ake_no_stored_km send fail: ret(%d)\n", ret);
- return -1;
- }
-
- return 0;
-}
-
-static int do_send_ake_stored_km(struct hdcp_link_data *lk)
-{
- int ret;
- struct hdcp_msg_info msg_info;
- struct dp_ake_stored_km *m_stored_km;
-
- /* check abort state firstly,
- * if session is abored by Rx, Tx stops Authentication process
- */
- if (is_auth_aborted())
- return -TX_AUTH_ERROR_ABORT;
-
- ret = dp_send_protocol_msg(lk, DP_AKE_STORED_KM, &msg_info);
- if (ret < 0) {
- hdcp_err("send AKE_stored_km failed. ret(%d)\n", ret);
- return -1;
- }
-
- m_stored_km = (struct dp_ake_stored_km *)msg_info.msg;
- ret = hdcp_dplink_send(HDCP22_MSG_EKH_KM_W,
- m_stored_km->ekh_km,
- sizeof(m_stored_km->ekh_km));
- if (ret) {
- hdcp_err("ake_stored_km send fail: ret(%d)\n", ret);
- return -1;
- }
-
- ret = hdcp_dplink_send(HDCP22_MSG_M_W,
- m_stored_km->m,
- sizeof(m_stored_km->m));
- if (ret) {
- hdcp_err("ake_stored_km send fail: ret(%d)\n", ret);
- return -1;
- }
-
- return 0;
-}
-
-static int do_recv_ake_send_h_prime(struct hdcp_link_data *lk)
-{
- int ret;
- struct hdcp_msg_info msg_info;
- struct dp_ake_send_h_prime m_hprime;
-
- /* check abort state firstly,
- * if session is abored by Rx, Tx stops Authentication process
- */
- if (is_auth_aborted())
- return -TX_AUTH_ERROR_ABORT;
-
- ret = hdcp_dplink_recv(HDCP22_MSG_HPRIME_R,
- m_hprime.h_prime,
- sizeof(m_hprime.h_prime));
- if (ret) {
- hdcp_err("ake_send_h_prime recv fail: ret(%d)\n", ret);
- return -1;
- }
-
- memcpy(msg_info.msg, &m_hprime, sizeof(struct dp_ake_send_h_prime));
- msg_info.msg_len = sizeof(struct dp_ake_send_h_prime);
- ret = dp_recv_protocol_msg(lk, DP_AKE_SEND_H_PRIME, &msg_info);
- if (ret < 0) {
- hdcp_err("recv AKE_Send_H_Prime failed. ret(%d)\n", ret);
- return -1;
- }
-
- return 0;
-}
-
-static int do_recv_ake_send_pairing_info(struct hdcp_link_data *lk)
-{
- int ret;
- struct hdcp_msg_info msg_info;
- struct dp_ake_send_pairing_info m_pairing;
-
- /* check abort state firstly,
- * if session is abored by Rx, Tx stops Authentication process
- */
- if (is_auth_aborted())
- return -TX_AUTH_ERROR_ABORT;
-
- ret = hdcp_dplink_recv(HDCP22_MSG_EKH_KM_R,
- m_pairing.ekh_km,
- sizeof(m_pairing.ekh_km));
- if (ret) {
- hdcp_err("ake_send_pairing_info recv fail: ret(%d)\n", ret);
- return -1;
- }
-
- memcpy(msg_info.msg, &m_pairing, sizeof(struct dp_ake_send_pairing_info));
- msg_info.msg_len = sizeof(struct dp_ake_send_pairing_info);
- ret = dp_recv_protocol_msg(lk, DP_AKE_SEND_PAIRING_INFO, &msg_info);
- if (ret < 0) {
- hdcp_err("recv AKE_Send_Pairing_Info failed. ret(%d)\n", ret);
- return -1;
- }
-
- return 0;
-}
-
-static int do_send_lc_init(struct hdcp_link_data *lk)
-{
- int ret;
- struct hdcp_msg_info msg_info;
- struct dp_lc_init *m_lc_init;
-
- /* check abort state firstly,
- * if session is abored by Rx, Tx stops Authentication process
- */
- if (is_auth_aborted())
- return -TX_AUTH_ERROR_ABORT;
-
- ret = dp_send_protocol_msg(lk, DP_LC_INIT, &msg_info);
- if (ret < 0) {
- hdcp_err("send LC_init failed. ret(%d)\n", ret);
- return -1;
- }
-
- m_lc_init = (struct dp_lc_init *)msg_info.msg;
- ret = hdcp_dplink_send(HDCP22_MSG_RN_W,
- m_lc_init->rn,
- sizeof(m_lc_init->rn));
- if (ret) {
- hdcp_err("lc_init send fail: ret(%d)\n", ret);
- return -1;
- }
-
- return 0;
-}
-
-static int do_recv_lc_send_l_prime(struct hdcp_link_data *lk)
-{
- int ret;
- struct hdcp_msg_info msg_info;
- struct dp_lc_send_l_prime m_lprime;
-
- /* check abort state firstly,
- * if session is abored by Rx, Tx stops Authentication process
- */
- if (is_auth_aborted())
- return -TX_AUTH_ERROR_ABORT;
-
- ret = hdcp_dplink_recv(HDCP22_MSG_LPRIME_R,
- m_lprime.l_prime,
- sizeof(m_lprime.l_prime));
- if (ret) {
- hdcp_err("lc_send_l_prime recv fail. ret(%d)\n", ret);
- return -1;
- }
-
- memcpy(msg_info.msg, &m_lprime, sizeof(struct dp_lc_send_l_prime));
- msg_info.msg_len = sizeof(struct dp_lc_send_l_prime);
- ret = dp_recv_protocol_msg(lk, DP_LC_SEND_L_PRIME, &msg_info);
- if (ret < 0) {
- hdcp_err("HDCP recv LC_Send_L_prime failed. ret(%d)\n", ret);
- return -1;
- }
-
- return 0;
-}
-
-static int do_send_ske_send_eks(struct hdcp_link_data *lk)
-{
- int ret;
- struct hdcp_msg_info msg_info;
- struct dp_ske_send_eks *m_ske;
- /* todo:
- * Currently, SST mode only use 0x00 as type value
- * MST mode, HDCP driver get type value from DP driver
- */
- uint8_t type = 0x00;
-
- /* check abort state firstly,
- * if session is abored by Rx, Tx stops Authentication process
- */
- if (is_auth_aborted())
- return -TX_AUTH_ERROR_ABORT;
-
- ret = dp_send_protocol_msg(lk, DP_SKE_SEND_EKS, &msg_info);
- if (ret < 0) {
- hdcp_err("send SKE_SEND_EKS failed. ret(%d)\n", ret);
- return -1;
- }
-
- m_ske = (struct dp_ske_send_eks *)msg_info.msg;
- ret = hdcp_dplink_send(HDCP22_MSG_EDKEY_KS0_W,
- &m_ske->edkey_ks[0],
- sizeof(m_ske->edkey_ks)/2);
- if (ret) {
- hdcp_err("SKE_send_eks send fail. ret(%d)\n", ret);
- return -1;
- }
-
- ret = hdcp_dplink_send(HDCP22_MSG_EDKEY_KS1_W,
- &m_ske->edkey_ks[8],
- sizeof(m_ske->edkey_ks)/2);
- if (ret) {
- hdcp_err("SKE_send_eks send fail. ret(%x)\n", ret);
- return -1;
- }
-
- ret = hdcp_dplink_send(HDCP22_MSG_RIV_W,
- m_ske->riv,
- sizeof(m_ske->riv));
- if (ret) {
- hdcp_err("SKE_send_eks send fail. ret(%x)\n", ret);
- return -1;
- }
-
- /* HDCP errata defined stream type.
- * type info is send only for receiver
- */
- if (!lk->rx_ctx.repeater) {
- ret = hdcp_dplink_send(HDCP22_MSG_TYPE_W,
- &type,
- sizeof(uint8_t));
- if (ret) {
- hdcp_err("HDCP : SKE_send_eks type send fail: %x\n", ret);
- return -1;
- }
- }
-
- return 0;
-}
-
-static int cal_rcvid_list_size(uint8_t *rxinfo, uint32_t *rcvid_size)
-{
- struct rxinfo rx;
- int ret = 0;
- rxinfo_convert_arr2st(rxinfo, &rx);
-
- /* rx_list check */
- if (rx.max_dev_exd || rx.max_cascade_exd)
- return 1;
-
- *rcvid_size = rx.dev_count * HDCP_RCV_ID_LEN;
- return ret;
-}
-
-static int do_recv_rcvid_list(struct hdcp_link_data *lk)
-{
- int ret;
- struct dp_rp_send_rcvid_list m_rcvid;
- uint32_t rcvid_size = 0;
- struct hdcp_msg_info msg_info;
-
- /* check abort state firstly,
- * if session is abored by Rx, Tx stops Authentication process
- */
- if (is_auth_aborted())
- return -TX_AUTH_ERROR_ABORT;
-
- memset(&m_rcvid, 0x00, sizeof(m_rcvid));
-
- ret = hdcp_dplink_recv(HDCP22_MSG_RXINFO_R,
- m_rcvid.rx_info,
- sizeof(m_rcvid.rx_info));
- if (ret) {
- hdcp_err("verify_receiver_id_list rx_info rcv fail: ret(%d)\n", ret);
- return -1;
- }
-
- ret = hdcp_dplink_recv(HDCP22_MSG_SEQ_NUM_V_R,
- m_rcvid.seq_num_v,
- sizeof(m_rcvid.seq_num_v));
-
- if (ret) {
- hdcp_err("verify_receiver_id_list seq_num_v rcv fail: ret(%d)\n", ret);
- return -1;
- }
-
- if ((m_rcvid.seq_num_v[0] || m_rcvid.seq_num_v[1] || m_rcvid.seq_num_v[2]) && rp_ready < 2) {
- hdcp_err("Initial seq_num_v is non_zero.\n");
- return -1;
- }
-
- ret = hdcp_dplink_recv(HDCP22_MSG_VPRIME_R,
- m_rcvid.v_prime,
- sizeof(m_rcvid.v_prime));
- if (ret) {
- hdcp_err("verify_receiver_id_list seq_num_v rcv fail: ret(%d)\n", ret);
- return -1;
- }
-
- ret = cal_rcvid_list_size(m_rcvid.rx_info, &rcvid_size);
- if (ret) {
- hdcp_err("Cal_rcvid_list Fail ! (%d)\n", ret);
- return -1;
- }
-
- ret = hdcp_dplink_recv(HDCP22_MSG_RECV_ID_LIST_R,
- m_rcvid.rcvid_list,
- rcvid_size);
- if (ret) {
- hdcp_err("verify_receiver_id_list rcvid_list rcv fail: ret(%d)\n", ret);
- return -1;
- }
-
- memcpy(msg_info.msg, &m_rcvid, sizeof(struct dp_rp_send_rcvid_list));
- msg_info.msg_len = sizeof(struct dp_rp_send_rcvid_list);
- ret = dp_recv_protocol_msg(lk, DP_REPEATERAUTH_SEND_RECEIVERID_LIST, &msg_info);
- if (ret < 0) {
- hdcp_err("recv RepeaterAuth_Send_ReceiverID_List failed\n");
- return -1;
- }
-
- return 0;
-}
-
-static int do_send_rp_ack(struct hdcp_link_data *lk)
-{
- int ret;
- struct hdcp_msg_info msg_info;
- struct dp_rp_send_ack *m_ack;
-
- /* check abort state firstly,
- * if session is abored by Rx, Tx stops Authentication process
- */
- if (is_auth_aborted())
- return -TX_AUTH_ERROR_ABORT;
-
- ret = dp_send_protocol_msg(lk, DP_REPEATERAUTH_SEND_AKE, &msg_info);
- if (ret < 0) {
- hdcp_err("send RepeaterAuth_Send_Ack failed. ret(%d)\n", ret);
- return -1;
- }
-
- m_ack = (struct dp_rp_send_ack *)msg_info.msg;
- ret = hdcp_dplink_send(HDCP22_MSG_V_W,
- m_ack->v,
- sizeof(m_ack->v));
- if (ret) {
- hdcp_err("V send fail: ret(%d)\n", ret);
- return -1;
- }
-
- return 0;
-}
-
-static int do_send_rp_stream_manage(struct hdcp_link_data *lk)
-{
- int ret;
- struct hdcp_msg_info msg_info;
- struct dp_rp_stream_manage *m_strm;
- uint16_t stream_num;
-
- /* check abort state firstly,
- * if session is abored by Rx, Tx stops Authentication process
- */
- if (is_auth_aborted())
- return -TX_AUTH_ERROR_ABORT;
-
- ret = dp_send_protocol_msg(lk, DP_REPEATERAUTH_STREAM_MANAGE, &msg_info);
- if (ret < 0) {
- hdcp_err("send RepeaterAuth_Stream_Manage. ret(%d)\n", ret);
- return -1;
- }
-
- m_strm = (struct dp_rp_stream_manage *)msg_info.msg;
- ret = hdcp_dplink_send(HDCP22_MSG_SEQ_NUM_M_W,
- m_strm->seq_num_m,
- sizeof(m_strm->seq_num_m));
- if (ret) {
- hdcp_err("seq_num_M send fail. ret(%d)\n", ret);
- return -1;
- }
-
- ret = hdcp_dplink_send(HDCP22_MSG_K_W,
- m_strm->k,
- sizeof(m_strm->k));
- if (ret) {
- hdcp_err("k send fail. ret(%x)\n", ret);
- return -1;
- }
-
- stream_num = lk->tx_ctx.strm.dp.stream_num;
- ret = hdcp_dplink_send(HDCP22_MSG_STREAMID_TYPE_W,
- m_strm->streamid_type,
- stream_num * HDCP_RP_STREAMID_TYPE_LEN);
- if (ret) {
- hdcp_err("Streamid_Type send fail. ret(%x)\n", ret);
- return -1;
- }
-
- return 0;
-}
-
-static int do_recv_rp_stream_ready(struct hdcp_link_data *lk)
-{
- int ret;
- struct hdcp_msg_info msg_info;
- struct dp_rp_stream_ready m_strm_ready;
-
- /* check abort state firstly,
- * if session is abored by Rx, Tx stops Authentication process
- */
- if (is_auth_aborted())
- return -TX_AUTH_ERROR_ABORT;
-
- ret = hdcp_dplink_recv(HDCP22_MSG_MPRIME_R,
- m_strm_ready.m_prime,
- sizeof(m_strm_ready.m_prime));
- if (ret) {
- hdcp_err("M' recv fail. ret(%d)\n", ret);
- return -1;
- }
-
- memcpy(msg_info.msg, &m_strm_ready, sizeof(struct dp_rp_stream_ready));
- msg_info.msg_len = sizeof(struct dp_rp_stream_ready);
- ret = dp_recv_protocol_msg(lk, DP_REPEATERAUTH_STREAM_READY, &msg_info);
- if (ret < 0) {
- hdcp_err("HDCP recv RepeaterAuth_Stream_Ready failed. ret(%d)\n", ret);
- return -1;
- }
-
- return 0;
-}
-
-static int check_h_prime_ready(void)
-{
- int i = 0;
- uint8_t status = 0;
-
- /* check abort state firstly,
- * if session is abored by Rx, Tx stops Authentication process
- */
- if (is_auth_aborted())
- return -TX_AUTH_ERROR_ABORT;
-
- msleep(110);
-
- /* HDCP spec is 1 sec. but we give margin 110ms */
- while (i < 10) {
- /* check abort state firstly,
- * if session is abored by Rx, Tx stops Authentication process
- */
- if (is_auth_aborted())
- return -TX_AUTH_ERROR_ABORT;
-
- /* received from CP_IRQ */
- if (hprime_ready) {
- /* reset flag */
- hprime_ready = 0;
- return 0;
- }
-
- /* check as polling mode */
- hdcp_dplink_get_rxinfo(&status);
- if (status & DP_RXSTATUS_HPRIME_AVAILABLE) {
- /* reset flag */
- hprime_ready = 0;
- return 0;
- }
-
- msleep(110);
- i++;
- }
-
- hdcp_err("hprime timeout(%dms)\n", (110 * i));
- return -1;
-}
-
-static int check_pairing_ready(void)
-{
- int i = 0;
- uint8_t status = 0;
-
- /* check abort state firstly,
- * if session is abored by Rx, Tx stops Authentication process
- */
- if (is_auth_aborted())
- return -TX_AUTH_ERROR_ABORT;
-
- msleep(220);
- /* HDCP spec is 200ms. but we give margin 110ms */
- while (i < 2) {
- /* check abort state firstly,
- * if session is abored by Rx, Tx stops Authentication process
- */
- if (is_auth_aborted())
- return -TX_AUTH_ERROR_ABORT;
-
- /* received from CP_IRQ */
- if (pairing_ready) {
- /* reset flag */
- pairing_ready = 0;
- return 0;
- }
-
- /* check as polling mode */
- hdcp_dplink_get_rxinfo(&status);
- if (status & DP_RXSTATUS_PAIRING_AVAILABLE) {
- /* reset flag */
- pairing_ready = 0;
- return 0;
- }
-
- msleep(110);
- i++;
- }
-
- hdcp_err("pairing timeout(%dms)\n", (110 * i));
- return -1;
-}
-
-static int check_rcvidlist_ready(void)
-{
- int i = 0;
- uint8_t status = 0;
-
- /* HDCP spec is 3 sec */
- while (i < 30) {
- /* check abort state firstly,
- * if session is abored by Rx, Tx stops Authentication process
- */
- if (is_auth_aborted())
- return -TX_AUTH_ERROR_ABORT;
-
- /* received from CP_IRQ */
- if (rp_ready > rp_ready_s) {
- /* reset flag */
- rp_ready_s = rp_ready;
- return 0;
- }
-
- /* check as polling mode */
- hdcp_dplink_get_rxinfo(&status);
- if (status & DP_RXSTATUS_READY) {
- rp_ready++;
- return 0;
- }
-
- msleep(110);
- i++;
- }
-
-
- hdcp_err("receiver ID list timeout(%dms)\n", (110 * i));
- return -TX_AUTH_ERROR_TIME_EXCEED;
-}
-
-int dplink_exchange_master_key(struct hdcp_link_data *lk)
-{
- int rval = TX_AUTH_SUCCESS;
- int key_found;
-
- do {
- /* send Tx -> Rx: AKE_init */
- if (do_send_ake_init(lk) < 0) {
- hdcp_err("send_ake_int fail\n");
- rval = -TX_AUTH_ERROR_SEND_PROTO_MSG;
- break;
- }
-
- /* HDCP spec defined 110ms as min delay after write AKE_Init */
- msleep(110);
-
- /* recv Rx->Tx: AKE_Send_Cert message */
- if (do_recv_ake_send_cert(lk) < 0) {
- hdcp_err("recv_ake_send_cert fail\n");
- rval = -TX_AUTH_ERROR_RECV_PROTO_MSG;
- break;
- }
-
- /* send Tx->Rx: AKE_Stored_km or AKE_No_Stored_km message */
- if (dp_ake_find_masterkey(&key_found) < 0) {
- hdcp_err("find master key fail\n");
- rval = -TX_AUTH_ERROR_MAKE_PROTO_MSG;
- break;
- }
- if (!key_found) {
- if (do_send_ake_nostored_km(lk) < 0) {
- hdcp_err("ake_send_nostored_km fail\n");
- rval = -TX_AUTH_ERROR_SEND_PROTO_MSG;
- break;
- }
- lk->stored_km = HDCP_WITHOUT_STORED_KM;
- } else {
- if (do_send_ake_stored_km(lk) < 0) {
- hdcp_err("ake_send_stored_km fail\n");
- rval = -TX_AUTH_ERROR_SEND_PROTO_MSG;
- break;
- }
- lk->stored_km = HDCP_WITH_STORED_KM;
- }
-
- if (check_h_prime_ready() < 0) {
- hdcp_err("Cannot read H prime\n");
- rval = -TX_AUTH_ERROR_RECV_PROTO_MSG;
- break;
- }
-
- /* recv Rx->Tx: AKE_Send_H_Prime message */
- if (do_recv_ake_send_h_prime(lk) < 0) {
- hdcp_err("recv_ake_send_h_prime fail\n");
- rval = -TX_AUTH_ERROR_RECV_PROTO_MSG;
- break;
- }
-
- if (lk->stored_km == HDCP_WITHOUT_STORED_KM) {
- if (check_pairing_ready() < 0) {
- hdcp_err("Cannot read pairing info\n");
- rval = -TX_AUTH_ERROR_RECV_PROTO_MSG;
- break;
- }
-
- /* recv Rx->Tx: AKE_Send_Pairing_Info message */
- if (do_recv_ake_send_pairing_info(lk) < 0) {
- hdcp_err("recv_ake_send_h_prime fail\n");
- rval = -TX_AUTH_ERROR_RECV_PROTO_MSG;
- break;
- }
- }
- } while (0);
-
- return rval;
-}
-
-int dplink_locality_check(struct hdcp_link_data *lk)
-{
- int i;
-
- for (i = 0; i < MAX_LC_RETRY; i++) {
- /* send Tx -> Rx: LC_init */
- if (do_send_lc_init(lk) < 0) {
- hdcp_err("send_lc_init fail\n");
- return -TX_AUTH_ERROR_SEND_PROTO_MSG;
- }
-
- /* wait until max dealy */
- msleep(16);
-
- /* recv Rx -> Tx: LC_Send_L_Prime */
- if (do_recv_lc_send_l_prime(lk) < 0) {
- hdcp_err("recv_lc_send_l_prime fail\n");
- /* retry */
- continue;
- } else {
- hdcp_debug("LC success. retryed(%d)\n", i);
- break;
- }
- }
-
- if (i == MAX_LC_RETRY) {
- hdcp_err("LC check fail. exceed retry count(%d)\n", i);
- return -TX_AUTH_ERROR_RETRYCOUNT_EXCEED;
- }
-
- return TX_AUTH_SUCCESS;
-}
-
-int dplink_exchange_session_key(struct hdcp_link_data *lk)
-{
- /* find session key from the session data */
- if (dp_get_hdcp_session_key(lk) < 0) {
- hdcp_err("dp_get_hdcp_session_key() failed\n");
- return -TX_AUTH_ERRRO_RESTORE_SKEY;
- }
-
- /* Send Tx -> Rx: SKE_Send_Eks */
- if (do_send_ske_send_eks(lk) < 0) {
- hdcp_err("send_ske_send_eks fail\n");
- return -TX_AUTH_ERROR_SEND_PROTO_MSG;
- }
-
- if (dp_put_hdcp_session_key(lk) < 0) {
- hdcp_err("put_hdcp_session_key() failed\n");
- return -TX_AUTH_ERROR_STORE_SKEY;
- }
-
- return TX_AUTH_SUCCESS;
-}
-
-int dplink_evaluate_repeater(struct hdcp_link_data *lk)
-{
- if (lk->rx_ctx.repeater)
- return TRUE;
- else
- return FALSE;
-}
-
-int dplink_wait_for_receiver_id_list(struct hdcp_link_data *lk)
-{
- int ret;
-
- ret = check_rcvidlist_ready();
- if (ret < 0)
- return ret;
- else
- return TX_AUTH_SUCCESS;
-}
-
-int dplink_verify_receiver_id_list(struct hdcp_link_data *lk)
-{
- /* recv Rx->Tx: RepeaterAuth_ReceiverID_List message */
- if (do_recv_rcvid_list(lk) < 0) {
- hdcp_err("recv_receiverID_list fail\n");
- return -TX_AUTH_ERROR_RECV_PROTO_MSG;
- }
-
- return TX_AUTH_SUCCESS;
-}
-
-int dplink_send_receiver_id_list_ack(struct hdcp_link_data *lk)
-{
- /* Send Tx -> Rx: RepeaterAuth_Send_Ack */
- if (do_send_rp_ack(lk) < 0) {
- hdcp_err("send_rp_ack fail\n");
- return -TX_AUTH_ERROR_SEND_PROTO_MSG;
- }
-
- return TX_AUTH_SUCCESS;
-}
-
-int dplink_determine_rx_hdcp_cap(struct hdcp_link_data *lk)
-{
- int ret;
- uint8_t rxcaps[HDCP_CAPS_BYTE_LEN];
-
- ret = hdcp_dplink_recv(HDCP22_MSG_RXCAPS_R,
- rxcaps,
- sizeof(rxcaps));
- if (ret) {
- hdcp_err("check rx caps recv fail: ret(%d)\n", ret);
- return -1;
- }
-
- if (!(rxcaps[2] & DP_RXCAPS_HDCP_CAPABLE)) {
- hdcp_err("Rx is not support HDCP. rxcaps(0x%02x%02x%02x)\n",
- rxcaps[0], rxcaps[1], rxcaps[2]);
- return -1;
- }
-
- if (rxcaps[0] != DP_RXCAPS_HDCP_VERSION_2) {
- hdcp_err("Rx is not HDCP2.x. rxcaps(0x%02x%02x%02x)\n",
- rxcaps[0], rxcaps[1], rxcaps[2]);
- return -1;
- }
-
- return 0;
-}
-
-int dplink_stream_manage(struct hdcp_link_data *lk)
-{
- /* Send Tx -> Rx: RepeaterAuth_Stream_Manage */
- if (do_send_rp_stream_manage(lk) < 0) {
- hdcp_err("send_rp_stream_manage fail\n");
- return -TX_AUTH_ERROR_SEND_PROTO_MSG;
- }
-
- /* HDCP spec define 110ms as min delay. But we give 110ms margin */
- msleep(220);
-
- /* recv Rx->Tx: RepeaterAuth_Stream_Ready message */
- if (do_recv_rp_stream_ready(lk) < 0) {
- hdcp_err("recv_rp_stream_ready fail\n");
- return -TX_AUTH_ERROR_RECV_PROTO_MSG;
- }
-
- return TX_AUTH_SUCCESS;
-}
-
-int dplink_set_paring_available(void)
-{
- pairing_ready = 1;
-
- return 0;
-}
-
-int dplink_set_hprime_available(void)
-{
- hprime_ready = 1;
-
- return 0;
-}
-
-int dplink_set_rp_ready(void)
-{
- rp_ready++;
- return 0;
-}
-
-int dplink_set_reauth_req(void)
-{
- reauth_req = 1;
-
- return 0;
-}
-
-int dplink_set_integrity_fail(void)
-{
- dplink_clear_irqflag_all();
- integrity_fail = 1;
-
- return 0;
-}
-
-void dplink_clear_irqflag_all(void)
-{
- pairing_ready = 0;
- hprime_ready = 0;
- rp_ready = 0;
- rp_ready_s = 0;
- reauth_req = 0;
- integrity_fail = 0;
-}
diff --git a/exynos-hdcp2-dplink-auth.h b/exynos-hdcp2-dplink-auth.h
deleted file mode 100644
index b7733a9..0000000
--- a/exynos-hdcp2-dplink-auth.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* drivers/soc/samsung/exynos-hdcp/dplink/exynos-hdcp2-dplink-auth.h
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-#ifndef __EXYNOS_HDCP2_DPLINK_AUTH_H__
-#define __EXYNOS_HDCP2_DPLINK_AUTH_H__
-
-#include "exynos-hdcp2-dplink-protocol-msg.h"
-
-int dplink_determine_rx_hdcp_cap(struct hdcp_link_data *lk);
-int dplink_exchange_master_key(struct hdcp_link_data *lk);
-int dplink_locality_check(struct hdcp_link_data *lk);
-int dplink_exchange_session_key(struct hdcp_link_data *lk);
-int dplink_evaluate_repeater(struct hdcp_link_data *lk);
-int dplink_wait_for_receiver_id_list(struct hdcp_link_data *lk);
-int dplink_verify_receiver_id_list(struct hdcp_link_data *lk);
-int dplink_send_receiver_id_list_ack(struct hdcp_link_data *lk);
-int dplink_stream_manage(struct hdcp_link_data *lk);
-int dplink_get_rxstatus(uint8_t *status);
-int dplink_set_paring_available(void);
-int dplink_set_hprime_available(void);
-int dplink_set_rp_ready(void);
-int dplink_set_reauth_req(void);
-int dplink_set_integrity_fail(void);
-void dplink_clear_irqflag_all(void);
-
-#endif
diff --git a/exynos-hdcp2-dplink-if.c b/exynos-hdcp2-dplink-if.c
deleted file mode 100644
index 8d53f22..0000000
--- a/exynos-hdcp2-dplink-if.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * drivers/soc/samsung/exynos_hdcp/dp_link/exynos-hdcp2-dplink-if.c
- *
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <net/sock.h>
-#include <linux/netlink.h>
-#include <linux/skbuff.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-#include "exynos-hdcp2-log.h"
-#include "exynos-hdcp2-dplink-reg.h"
-#include "exynos-hdcp2-dplink-if.h"
-
-static void (*pdp_hdcp22_enable)(u32 en);
-static int (*pdp_dpcd_read_for_hdcp22)(u32 address, u32 length, u8 *data);
-static int (*pdp_dpcd_write_for_hdcp22)(u32 address, u32 length, u8 *data);
-
-/* Address define for HDCP within DPCD address space */
-static uint32_t dpcd_addr[NUM_HDCP_MSG_NAME] = {
- DPCD_ADDR_HDCP13_Bksv,
- DPCD_ADDR_HDCP13_Ri_prime,
- DPCD_ADDR_HDCP13_Aksv,
- DPCD_ADDR_HDCP13_An,
- DPCD_ADDR_HDCP13_Vprime,
- DPCD_ADDR_HDCP13_Bcaps,
- DPCD_ADDR_HDCP13_Bstatus,
- DPCD_ADDR_HDCP13_Binfo,
- DPCD_ADDR_HDCP13_Ksv_fifo,
- DPCD_ADDR_HDCP22_Rtx,
- DPCD_ADDR_HDCP22_TxCaps,
- DPCD_ADDR_HDCP22_cert_rx,
- DPCD_ADDR_HDCP22_Rrx,
- DPCD_ADDR_HDCP22_RxCaps,
- DPCD_ADDR_HDCP22_Ekpub_km,
- DPCD_ADDR_HDCP22_Ekh_km_w,
- DPCD_ADDR_HDCP22_m,
- DPCD_ADDR_HDCP22_Hprime,
- DPCD_ADDR_HDCP22_Ekh_km_r,
- DPCD_ADDR_HDCP22_rn,
- DPCD_ADDR_HDCP22_Lprime,
- DPCD_ADDR_HDCP22_Edkey0_ks,
- DPCD_ADDR_HDCP22_Edkey1_ks,
- DPCD_ADDR_HDCP22_riv,
- DPCD_ADDR_HDCP22_RxInfo,
- DPCD_ADDR_HDCP22_seq_num_V,
- DPCD_ADDR_HDCP22_Vprime,
- DPCD_ADDR_HDCP22_Rec_ID_list,
- DPCD_ADDR_HDCP22_V,
- DPCD_ADDR_HDCP22_seq_num_M,
- DPCD_ADDR_HDCP22_k,
- DPCD_ADDR_HDCP22_stream_IDtype,
- DPCD_ADDR_HDCP22_Mprime,
- DPCD_ADDR_HDCP22_RxStatus,
- DPCD_ADDR_HDCP22_Type,
-};
-
-void hdcp_dplink_config(int en)
-{
- pdp_hdcp22_enable(en);
-}
-
-int hdcp_dplink_is_enabled_hdcp22(void)
-{
- /* todo: check hdcp22 enable */
- return 1;
-}
-
-/* todo: get stream info from DP */
-#define HDCP_DP_STREAM_NUM 0x01
-static uint8_t stream_id[1] = {0x00};
-int hdcp_dplink_get_stream_info(uint16_t *num, uint8_t *strm_id)
-{
- *num = HDCP_DP_STREAM_NUM;
- memcpy(strm_id, stream_id, sizeof(uint8_t) * (*num));
-
- return 0;
-}
-
-int hdcp_dplink_recv(uint32_t msg_name, uint8_t *data, uint32_t size)
-{
- return pdp_dpcd_read_for_hdcp22(dpcd_addr[msg_name], size, data);
-}
-
-int hdcp_dplink_send(uint32_t msg_name, uint8_t *data, uint32_t size)
-{
- return pdp_dpcd_write_for_hdcp22(dpcd_addr[msg_name], size, data);
-}
-
-void dp_register_func_for_hdcp22(void (*func0)(u32 en), int (*func1)(u32 address, u32 length, u8 *data), int (*func2)(u32 address, u32 length, u8 *data))
-{
- pdp_hdcp22_enable = func0;
- pdp_dpcd_read_for_hdcp22 = func1;
- pdp_dpcd_write_for_hdcp22 = func2;
-}
-EXPORT_SYMBOL_GPL(dp_register_func_for_hdcp22);
diff --git a/exynos-hdcp2-dplink-if.h b/exynos-hdcp2-dplink-if.h
deleted file mode 100644
index feff163..0000000
--- a/exynos-hdcp2-dplink-if.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* driver/soc/samsung/exynos-hdcp/dplink/exynos-hdcp2-dplink-if.h
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-#ifndef __EXYNOS_HDCP2_DPLINK_IF_H__
-#define __EXYNOS_HDCP2_DPLINK_IF_H__
-
-enum hdcp_msg_name {
- HDCP13_MSG_BKSV_R,
- HDCP13_MSG_RI_PRIME_R,
- HDCP13_MSG_AKSV_W,
- HDCP13_MSG_AN_W,
- HDCP13_MSG_VPRIME_R,
- HDCP13_MSG_BCAPS_R,
- HDCP13_MSG_BSTATUS_R,
- HDCP13_MSG_BINFO_R,
- HDCP13_MSG_KSV_FIFO_R,
- HDCP22_MSG_RTX_W,
- HDCP22_MSG_TXCAPS_W,
- HDCP22_MSG_CERT_RX_R,
- HDCP22_MSG_RRX_R,
- HDCP22_MSG_RXCAPS_R,
- HDCP22_MSG_EKPUB_KM_W,
- HDCP22_MSG_EKH_KM_W,
- HDCP22_MSG_M_W,
- HDCP22_MSG_HPRIME_R,
- HDCP22_MSG_EKH_KM_R,
- HDCP22_MSG_RN_W,
- HDCP22_MSG_LPRIME_R,
- HDCP22_MSG_EDKEY_KS0_W,
- HDCP22_MSG_EDKEY_KS1_W,
- HDCP22_MSG_RIV_W,
- HDCP22_MSG_RXINFO_R,
- HDCP22_MSG_SEQ_NUM_V_R,
- HDCP22_MSG_VPRIME_R,
- HDCP22_MSG_RECV_ID_LIST_R,
- HDCP22_MSG_V_W,
- HDCP22_MSG_SEQ_NUM_M_W,
- HDCP22_MSG_K_W,
- HDCP22_MSG_STREAMID_TYPE_W,
- HDCP22_MSG_MPRIME_R,
- HDCP22_MSG_RXSTATUS_R,
- HDCP22_MSG_TYPE_W,
- NUM_HDCP_MSG_NAME,
-};
-
-#define DP_HDCP22_DISABLE 0
-#define DP_HDCP22_ENABLE 1
-#define DP_HPD_STATUS_ZERO 2
-
-void hdcp_dplink_config(int en);
-int hdcp_dplink_is_enabled_hdcp22(void);
-int hdcp_dplink_recv(uint32_t msg_name, uint8_t *data, uint32_t size);
-int hdcp_dplink_send(uint32_t msg_name, uint8_t *data, uint32_t size);
-int hdcp_dplink_get_stream_info(uint16_t *num, uint8_t *strm_id);
-void dp_register_func_for_hdcp22(void (*func0)(u32 en), int (*func1)(u32 address, u32 length, u8 *data), int (*func2)(u32 address, u32 length, u8 *data));
-
-#endif
diff --git a/exynos-hdcp2-dplink-inter.c b/exynos-hdcp2-dplink-inter.c
deleted file mode 100644
index 5344375..0000000
--- a/exynos-hdcp2-dplink-inter.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * drivers/soc/samsung/exynos-hdcp/dp_link/exynos-hdcp2-dplink.c
- *
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <drm/drm_dp_helper.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-#include <linux/smc.h>
-#include <asm/cacheflush.h>
-#include <linux/soc/samsung/exynos-smc.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-
-#include "exynos-hdcp1-auth.h"
-#include "exynos-hdcp2.h"
-#include "exynos-hdcp2-log.h"
-#include "exynos-hdcp2-dplink.h"
-#include "exynos-hdcp2-dplink-inter.h"
-#include "exynos-hdcp2-dplink-if.h"
-#include "exynos-hdcp2-dplink-auth.h"
-#include "exynos-hdcp2-teeif.h"
-
-#define DRM_WAIT_RETRY_COUNT 1000
-/* current link data */
-enum auth_state auth_proc_state;
-enum dp_state dp_hdcp_state;
-
-int hdcp_dplink_auth_control(enum auth_signal hdcp_signal)
-{
- switch (hdcp_signal) {
- case HDCP_OFF:
- return 0;
- case HDCP1_ON:
- hdcp13_dplink_authenticate();
- return 0;
- case HDCP2_ON:
- dplink_clear_irqflag_all();
- return hdcp_dplink_authenticate();
- default:
- return HDCP_ERROR_INVALID_STATE;
- break;
- }
- return 0;
-}
-EXPORT_SYMBOL_GPL(hdcp_dplink_auth_control);
-
-int hdcp_dplink_handle_hdcp22_irq(void) {
- uint8_t rxstatus = 0;
- hdcp_dplink_get_rxinfo(&rxstatus);
-
- if (HDCP_2_2_DP_RXSTATUS_LINK_FAILED(rxstatus)) {
- hdcp_info("integrity check fail.\n");
- hdcp_tee_disable_enc();
- dplink_set_integrity_fail();
- return 0;
- } else if (HDCP_2_2_DP_RXSTATUS_REAUTH_REQ(rxstatus)) {
- hdcp_info("reauth requested.\n");
- hdcp_tee_disable_enc();
- dplink_set_reauth_req();
- return -EAGAIN;
- } else if (HDCP_2_2_DP_RXSTATUS_PAIRING(rxstatus)) {
- hdcp_info("pairing avaible\n");
- dplink_set_paring_available();
- return 0;
- } else if (HDCP_2_2_DP_RXSTATUS_H_PRIME(rxstatus)) {
- hdcp_info("h-prime avaible\n");
- dplink_set_hprime_available();
- return 0;
- } else if (HDCP_2_2_DP_RXSTATUS_READY(rxstatus)) {
- hdcp_info("ready avaible\n");
- dplink_set_rp_ready();
- if (auth_proc_state == HDCP2_AUTH_PROCESS_DONE) {
- if (hdcp_dplink_authenticate() == 0)
- auth_proc_state = HDCP2_AUTH_PROCESS_DONE;
- }
- return 0;
- }
-
- hdcp_err("undefined RxStatus(0x%x). ignore\n", rxstatus);
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(hdcp_dplink_handle_hdcp22_irq);
-
-int hdcp_dplink_handle_hdcp13_irq(void)
-{
- uint8_t bstatus;
-
- if (auth_proc_state != HDCP1_AUTH_PROCESS_DONE) {
- hdcp_err("Ignoring IRQ during auth\n");
- return 0;
- }
-
- hdcp_dplink_recv(HDCP13_MSG_BSTATUS_R, &bstatus,
- sizeof(bstatus));
-
- if (bstatus & DP_BSTATUS_LINK_FAILURE ||
- bstatus & DP_BSTATUS_REAUTH_REQ) {
- hdcp_err("Resetting link and encryption\n");
- hdcp_tee_disable_enc();
- return -EAGAIN;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(hdcp_dplink_handle_hdcp13_irq);
-
-int hdcp_dplink_cancel_auth(void)
-{
- hdcp_info("Cancel authenticate.\n");
- hdcp_tee_disable_enc();
- auth_proc_state = HDCP_AUTH_PROCESS_STOP;
-
- return dplink_set_integrity_fail();
-}
-EXPORT_SYMBOL_GPL(hdcp_dplink_cancel_auth);
-
-void hdcp_dplink_clear_all(void)
-{
- hdcp_info("HDCP flag clear\n");
- hdcp_tee_disable_enc();
- dplink_clear_irqflag_all();
-}
-EXPORT_SYMBOL_GPL(hdcp_dplink_clear_all);
-
-void hdcp_dplink_connect_state(enum dp_state state)
-{
- dp_hdcp_state = state;
- hdcp_info("Displayport connect info (%d)\n", dp_hdcp_state);
- hdcp_tee_connect_info((int)dp_hdcp_state);
-}
-EXPORT_SYMBOL_GPL(hdcp_dplink_connect_state);
-
-int hdcp_dplink_auth_check(enum auth_signal hdcp_signal)
-{
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(hdcp_dplink_auth_check);
-
-int hdcp_dplink_get_rxstatus(uint8_t *status)
-{
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(hdcp_dplink_get_rxstatus);
-
-int hdcp_dplink_set_paring_available(void)
-{
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(hdcp_dplink_set_paring_available);
-
-int hdcp_dplink_set_hprime_available(void)
-{
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(hdcp_dplink_set_hprime_available);
-
-int hdcp_dplink_set_rp_ready(void)
-{
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(hdcp_dplink_set_rp_ready);
-
-int hdcp_dplink_set_reauth(void)
-{
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(hdcp_dplink_set_reauth);
-
-int hdcp_dplink_set_integrity_fail(void)
-{
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(hdcp_dplink_set_integrity_fail);
-
diff --git a/exynos-hdcp2-dplink-inter.h b/exynos-hdcp2-dplink-inter.h
deleted file mode 100644
index 763a1d4..0000000
--- a/exynos-hdcp2-dplink-inter.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* driver/soc/samsung/exynos-hdcp/dplink/exynos-hdcp2-dplink.h
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-#ifndef __EXYNOS_HDCP2_DPLINK_INTER_H__
-#define __EXYNOS_HDCP2_DPLINK_INTER_H__
-
-/* Do hdcp2.2 authentication with DP Receiver
- * and enable encryption if authentication is succeed.
- * @return
- * - 0: Success
- * - ENOMEM: hdcp context open fail
- * - EACCES: authentication fail
- */
-int hdcp_dplink_get_rxstatus(uint8_t *status);
-int hdcp_dplink_set_paring_available(void);
-int hdcp_dplink_set_hprime_available(void);
-int hdcp_dplink_set_rp_ready(void);
-int hdcp_dplink_set_reauth(void);
-int hdcp_dplink_set_integrity_fail(void);
-int hdcp_dplink_cancel_auth(void);
-int hdcp_dplink_stream_manage(void);
-int hdcp_dplink_auth_check(enum auth_signal);
-int hdcp_dplink_auth_control(enum auth_signal);
-void hdcp_dplink_clear_all(void);
-void hdcp_dplink_connect_state(enum dp_state state);
-int hdcp_dplink_handle_hdcp13_irq(void);
-int hdcp_dplink_handle_hdcp22_irq(void);
-#endif
diff --git a/exynos-hdcp2-dplink-protocol-msg.c b/exynos-hdcp2-dplink-protocol-msg.c
deleted file mode 100644
index 1c36f6d..0000000
--- a/exynos-hdcp2-dplink-protocol-msg.c
+++ /dev/null
@@ -1,492 +0,0 @@
-/*
- * drivers/soc/samsung/exynos-hdcp/dp_link/exynos-hdcp2-dplink-protocol-msg.c
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include "exynos-hdcp2-protocol-msg.h"
-#include "exynos-hdcp2.h"
-#include "exynos-hdcp2-log.h"
-#include "exynos-hdcp2-dplink-protocol-msg.h"
-#include "exynos-hdcp2-dplink-if.h"
-
-/* HDCP protocol message capulate & decapulate functions for DP */
-static int dp_cap_ake_init(uint8_t *m, size_t *m_len,
- struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx);
-static int dp_cap_ake_no_stored_km(uint8_t *m, size_t *m_len,
- struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx);
-static int dp_cap_ake_stored_km(uint8_t *m, size_t *m_len,
- struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx);
-static int dp_decap_ake_send_cert(uint8_t *m, size_t *m_len,
- struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx);
-static int dp_decap_ake_send_h_prime(uint8_t *m, size_t *m_len,
- struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx);
-static int dp_decap_ake_send_pairing_info(uint8_t *m, size_t *m_len,
- struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx);
-static int dp_cap_lc_init(uint8_t *m, size_t *m_len,
- struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx);
-static int dp_decap_lc_send_l_prime(uint8_t *m, size_t *m_len,
- struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx);
-static int dp_cap_ske_send_eks(uint8_t *m, size_t *m_len,
- struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx);
-static int dp_decap_rpauth_send_recvid_list(uint8_t *m, size_t *m_len,
- struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx);
-static int dp_cap_rpauth_send_ack(uint8_t *m, size_t *m_len,
- struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx);
-static int dp_cap_rpauth_stream_manage(uint8_t *m, size_t *m_len,
- struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx);
-static int dp_decap_rpauth_stream_ready(uint8_t *m, size_t *m_len,
- struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx);
-static int (*proto_dp[])(uint8_t *, size_t *,
- struct hdcp_tx_ctx *,
- struct hdcp_rx_ctx *) = {
- dp_cap_ake_init,
- dp_decap_ake_send_cert,
- dp_cap_ake_no_stored_km,
- dp_cap_ake_stored_km,
- NULL, /* not defined in HDCP2.2 DP spec */
- dp_decap_ake_send_h_prime,
- dp_decap_ake_send_pairing_info,
- dp_cap_lc_init,
- dp_decap_lc_send_l_prime,
- dp_cap_ske_send_eks,
- dp_decap_rpauth_send_recvid_list,
- NULL, /* not defined in HDCP2.2 DP spec */
- NULL, /* not defined in HDCP2.2 DP spec */
- dp_cap_rpauth_send_ack,
- dp_cap_rpauth_stream_manage,
- dp_decap_rpauth_stream_ready,
- NULL, /* to do */
- NULL, /* not defined in HDCP2.2 DP spec */
- NULL, /* not defined in HDCP2.2 DP spec */
-};
-
-static int dp_rp_verify_stream_ready(uint8_t *m_prime)
-{
- int ret;
-
- ret = teei_verify_m_prime(m_prime, NULL, 0);
- if (ret) {
- hdcp_err("teei_verify_m_prime() is failed with %x\n", ret);
- return ERR_RP_INVALID_M_PRIME;
- }
-
- return 0;
-}
-
-static int dp_rp_gen_stream_manage(struct dp_stream_info *strm)
-{
- int ret;
-
- ret = teei_gen_stream_manage(strm->stream_num,
- strm->streamid,
- strm->seq_num_m,
- strm->k,
- strm->streamid_type);
- if (ret) {
- hdcp_err("teei_gen_stream_manage() is failed with %x\n", ret);
- return ERR_RP_GEN_STREAM_MG;
- }
-
- return 0;
-}
-
-static int dp_rp_set_rcvid_list(struct hdcp_rpauth_info *rp)
-{
- int ret;
-
- ret = teei_set_rcvlist_info(rp->rx_info,
- rp->seq_num_v,
- rp->v_prime,
- rp->u_rcvid.lst,
- rp->v,
- &rp->valid);
- if (ret) {
- hdcp_err("teei_set_rcvid_list() is failed with %x\n", ret);
- return ERR_RP_VERIFY_RCVLIST;
- }
-
- return 0;
-}
-
-static int dp_ake_generate_rtx(uint8_t *rtx, size_t rtx_len,
- uint8_t *caps, uint32_t caps_len)
-{
- int ret;
-
- ret = teei_gen_rtx(HDCP_LINK_TYPE_DP, rtx, rtx_len, caps, caps_len);
- if (ret) {
- hdcp_err("generate_none_secret_key() is failed with %x\n", ret);
- return ERR_GENERATE_NON_SECKEY;
- }
-
- return 0;
-}
-
-static int dp_cap_ake_init(uint8_t *m, size_t *m_len, struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx)
-{
- size_t rtx_len;
- uint32_t caps_len;
- int ret;
-
- /* Buffer Check */
- if ((m == NULL) || (m_len == NULL) || (tx_ctx == NULL))
- return ERR_WRONG_BUFFER;
-
- rtx_len = HDCP_AKE_RTX_BYTE_LEN;
- caps_len = HDCP_CAPS_BYTE_LEN;
-
- /* Generate rtx */
- ret = dp_ake_generate_rtx(tx_ctx->rtx, rtx_len,
- tx_ctx->caps, caps_len);
- if (ret) {
- hdcp_err("failed to generate rtx. ret(%d)\n", ret);
- return ERR_GENERATE_RTX;
- }
-
- /* Make Message */
- memcpy(&m[0], tx_ctx->rtx, rtx_len);
- memcpy(&m[rtx_len], tx_ctx->caps, HDCP_CAPS_BYTE_LEN);
- *m_len = rtx_len + HDCP_CAPS_BYTE_LEN;
-
- return 0;
-}
-
-static int dp_cap_ake_no_stored_km(uint8_t *m, size_t *m_len,
- struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx)
-{
- uint8_t enc_mkey[HDCP_AKE_ENCKEY_BYTE_LEN];
- int ret;
-
- if ((m == NULL) || (m_len == NULL) ||
- (tx_ctx == NULL) || (rx_ctx == NULL))
- return ERR_WRONG_BUFFER;
-
- /* Generate/Encrypt master key */
- ret = ake_generate_masterkey(HDCP_LINK_TYPE_DP,
- enc_mkey,
- sizeof(enc_mkey));
- /* Generate/Encrypt master key */
- if (ret)
- return ret;
-
- /* Make Message */
- memcpy(m, enc_mkey, HDCP_AKE_ENCKEY_BYTE_LEN);
- *m_len = HDCP_AKE_ENCKEY_BYTE_LEN;
-
- return 0;
-}
-
-static int dp_cap_ake_stored_km(uint8_t *m, size_t *m_len,
- struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx)
-{
- int found_km;
- int ret;
-
- if ((m == NULL) || (m_len == NULL) ||
- (tx_ctx == NULL) || (rx_ctx == NULL))
- return ERR_WRONG_BUFFER;
-
- ret = ake_find_masterkey(&found_km,
- tx_ctx->ekh_mkey, HDCP_AKE_EKH_MKEY_BYTE_LEN,
- tx_ctx->m, HDCP_AKE_M_BYTE_LEN);
- if (ret || !found_km) {
- hdcp_err("find_masterkey() is failed with ret(0x%x). found(%d)\n", ret, found_km);
- return -1;
- }
-
- /* Make Message */
- memcpy(m, tx_ctx->ekh_mkey, HDCP_AKE_EKH_MKEY_BYTE_LEN);
- memcpy(&m[HDCP_AKE_EKH_MKEY_BYTE_LEN], tx_ctx->m, HDCP_AKE_M_BYTE_LEN);
- *m_len = HDCP_AKE_EKH_MKEY_BYTE_LEN + HDCP_AKE_M_BYTE_LEN;
-
- return 0;
-}
-
-static int dp_decap_ake_send_cert(uint8_t *m, size_t *m_len, struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx)
-{
- int ret;
-
- ret = dp_check_received_msg(m, *m_len, HDCP_RX_CERT_LEN +
- HDCP_RRX_BYTE_LEN +
- HDCP_CAPS_BYTE_LEN);
- if (ret)
- return ret;
-
- ret = ake_verify_cert(m, HDCP_RX_CERT_LEN,
- &m[HDCP_RX_CERT_LEN], HDCP_RRX_BYTE_LEN,
- &m[HDCP_RX_CERT_LEN + HDCP_RRX_BYTE_LEN], HDCP_CAPS_BYTE_LEN);
- if (ret) {
- hdcp_err("teei_verify_cert is failed with %x\n", ret);
- return ERR_VERIFY_CERT;
- }
-
- return 0;
-}
-
-static int dp_decap_ake_send_h_prime(uint8_t *m, size_t *m_len, struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx)
-{
- int ret;
-
- /* compare H == H' */
- ret = ake_compare_hmac(m, HDCP_HMAC_SHA256_LEN);
- if (ret) {
- hdcp_err("decap_ake_send_h_prime is failed. ret(%d)\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-static int dp_decap_ake_send_pairing_info(uint8_t *m, size_t *m_len,
- struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx)
-{
- int ret;
-
- memcpy(tx_ctx->ekh_mkey, &m[0], HDCP_AKE_EKH_MKEY_BYTE_LEN);
-
- /* Store the Key */
- ret = ake_store_master_key(tx_ctx->ekh_mkey, HDCP_AKE_EKH_MKEY_BYTE_LEN);
- if (ret) {
- hdcp_err("failed to store master key. ret(%d)\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-int dp_cap_lc_init(uint8_t *m, size_t *m_len, struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx)
-{
- int ret;
-
- if ((m == NULL) || (m_len == NULL) || (tx_ctx == NULL) ||
- (rx_ctx == NULL))
- return ERR_WRONG_BUFFER;
-
- /* Generate rn */
- ret = lc_generate_rn(tx_ctx->rn, HDCP_RTX_BYTE_LEN);
- if (ret) {
- hdcp_err("failed to generate rtx. ret(%d)\n", ret);
- return ret;
- }
-
- /* Make Message */
- memcpy(m, tx_ctx->rn, HDCP_RTX_BYTE_LEN);
- *m_len = HDCP_RTX_BYTE_LEN;
-
- return 0;
-}
-
-static int dp_decap_lc_send_l_prime(uint8_t *m, size_t *m_len, struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx)
-{
- uint8_t *rx_hmac;
- size_t len;
- int ret;
-
- len = HDCP_HMAC_SHA256_LEN;
-
- /* No_precomputation: compare hmac
- precomputation: compare the most significant 128bits of L & L' */
- rx_hmac = m;
- ret = lc_compare_hmac(rx_hmac, len);
- if (ret)
- return ret;
-
- return 0;
-}
-
-static int dp_cap_ske_send_eks(uint8_t *m, size_t *m_len,
- struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx)
-{
- int ret;
- uint8_t enc_skey[HDCP_AKE_MKEY_BYTE_LEN];
-
- if ((m == NULL) || (m_len == NULL) || (tx_ctx == NULL) ||
- (rx_ctx == NULL))
- return ERR_WRONG_BUFFER;
-
- /* Generate riv */
- if (!tx_ctx->share_skey) {
- ret = ske_generate_riv(tx_ctx->riv);
- if (ret)
- return ERR_GENERATE_RIV;
- }
-
- /* Generate encrypted Session Key */
- ret = ske_generate_sessionkey(HDCP_LINK_TYPE_DP,
- enc_skey,
- tx_ctx->share_skey);
- if (ret)
- return ret;
-
- /* Make Message */
- memcpy(m, enc_skey, HDCP_AKE_MKEY_BYTE_LEN);
- memcpy(&m[HDCP_AKE_MKEY_BYTE_LEN], tx_ctx->riv, HDCP_RTX_BYTE_LEN);
- *m_len = HDCP_AKE_MKEY_BYTE_LEN + HDCP_RTX_BYTE_LEN;
-
- return 0;
-}
-
-static int dp_decap_rpauth_send_recvid_list(uint8_t *m,
- size_t *m_len,
- struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx)
-{
- int ret;
- struct hdcp_rpauth_info *rp;
-
- rp = &tx_ctx->rpauth_info;
-
- memcpy(rp->rx_info, &m[0], HDCP_RP_RX_INFO_LEN);
- memcpy(rp->seq_num_v, &m[HDCP_RP_RX_INFO_LEN], HDCP_RP_SEQ_NUM_V_LEN);
- memcpy(rp->v_prime, &m[HDCP_RP_RX_INFO_LEN + HDCP_RP_SEQ_NUM_V_LEN],
- HDCP_RP_HMAC_V_LEN / 2);
- memcpy(rp->u_rcvid.lst,
- &m[HDCP_RP_RX_INFO_LEN + HDCP_RP_SEQ_NUM_V_LEN + (HDCP_RP_HMAC_V_LEN / 2)],
- HDCP_RP_RCVID_LIST_LEN);
-
- /* set receiver id list */
- ret = dp_rp_set_rcvid_list(rp);
- if (ret) {
- hdcp_err("failed to set receiver id list. ret(%d)\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-static int dp_cap_rpauth_send_ack(uint8_t *m,
- size_t *m_len,
- struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx)
-{
- /* Make Message */
- if (tx_ctx->rpauth_info.valid == 0) {
- memcpy(m, tx_ctx->rpauth_info.v, HDCP_RP_HMAC_V_LEN / 2);
- *m_len = HDCP_RP_HMAC_V_LEN / 2;
- } else {
- *m_len = 0;
- return ERR_SEND_ACK;
- }
-
- return 0;
-}
-
-static int dp_cap_rpauth_stream_manage(uint8_t *m,
- size_t *m_len,
- struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx)
-{
- struct dp_stream_info *strm;
- int ret;
-
- strm = &tx_ctx->strm.dp;
-
- hdcp_dplink_get_stream_info(&strm->stream_num, strm->streamid);
-
- /* set receiver id list */
- ret = dp_rp_gen_stream_manage(strm);
- if (ret) {
- hdcp_err("failed to gen stream manage. ret(%d)\n", ret);
- return ret;
- }
-
- /* Make Message */
- memcpy(m, strm->seq_num_m, HDCP_RP_SEQ_NUM_M_LEN);
- memcpy(&m[HDCP_RP_SEQ_NUM_M_LEN], strm->k, HDCP_RP_K_LEN);
- memcpy(&m[HDCP_RP_SEQ_NUM_M_LEN + HDCP_RP_K_LEN],
- strm->streamid_type, HDCP_RP_STREAMID_TYPE_LEN * strm->stream_num);
-
- *m_len = HDCP_RP_SEQ_NUM_M_LEN + \
- HDCP_RP_K_LEN + \
- (HDCP_RP_STREAMID_TYPE_LEN * strm->stream_num);
-
- return 0;
-}
-
-static int dp_decap_rpauth_stream_ready(uint8_t *m,
- size_t *m_len,
- struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx)
-{
- uint8_t *m_prime;
- int ret;
-
- m_prime = m;
- ret = dp_rp_verify_stream_ready(m_prime);
- if (ret)
- hdcp_err("dp_rp_verify_stream_ready ret(%d)\n", ret);
-
- return 0;
-}
-
-int dp_cap_protocol_msg(uint8_t msg_id,
- uint8_t *msg,
- size_t *msg_len,
- struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx)
-{
- int ret = 0;
- int (**proto_func)(uint8_t *, size_t *,
- struct hdcp_tx_ctx *,
- struct hdcp_rx_ctx *);
- proto_func = proto_dp;
-
- if (msg_id > 1) {
- ret = proto_func[msg_id - 2](msg, msg_len, tx_ctx, rx_ctx);
- return ret;
- }
- else
- return -1;
-}
-
-int dp_decap_protocol_msg(uint8_t msg_id,
- uint8_t *msg,
- size_t msg_len,
- struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx)
-{
- int ret = 0;
- int (**proto_func)(uint8_t *, size_t *,
- struct hdcp_tx_ctx *,
- struct hdcp_rx_ctx *);
- proto_func = proto_dp;
-
- if (msg_id > 1) {
- ret = proto_func[msg_id - 2](msg, &msg_len, tx_ctx, rx_ctx);
- return ret;
- }
-
- else
- return -1;
-}
diff --git a/exynos-hdcp2-dplink-protocol-msg.h b/exynos-hdcp2-dplink-protocol-msg.h
deleted file mode 100644
index 2954fe0..0000000
--- a/exynos-hdcp2-dplink-protocol-msg.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* driver/soc/samsung/exynos-hdcp/dplink/exynos-hdcp2-protocol-msg.h
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-#ifndef __EXYNOS_HDCP2_DPLINK_PROTOCOL_MSG_H__
-#define __EXYNOS_HDCP2_DPLINK_PROTOCOL_MSG_H__
-
-#include <linux/types.h>
-
-enum dp_msg_id {
- DP_AKE_INIT = 2,
- DP_AKE_SEND_CERT,
- DP_AKE_NO_STORED_KM,
- DP_AKE_STORED_KM,
- DP_AKE_SEND_RRX,
- DP_AKE_SEND_H_PRIME,
- DP_AKE_SEND_PAIRING_INFO,
- DP_LC_INIT,
- DP_LC_SEND_L_PRIME,
- DP_SKE_SEND_EKS,
- DP_REPEATERAUTH_SEND_RECEIVERID_LIST,
- DP_RTT_READY,
- DP_RTT_CHALLENGE,
- DP_REPEATERAUTH_SEND_AKE,
- DP_REPEATERAUTH_STREAM_MANAGE,
- DP_REPEATERAUTH_STREAM_READY,
- DP_RECEIVER_AUTHSTATUS,
- DP_AKE_TRANSMITTER_INFO,
- DP_AKE_RECEIVER_INFO,
-};
-
-#define DP_RXSTATUS_READY (0x1 << 0)
-#define DP_RXSTATUS_HPRIME_AVAILABLE (0x1 << 1)
-#define DP_RXSTATUS_PAIRING_AVAILABLE (0x1 << 2)
-#define DP_RXSTATUS_REAUTH_REQ (0x1 << 3)
-#define DP_RXSTATUS_LINK_INTEGRITY_FAIL (0x1 << 4)
-
-#define DP_RXCAPS_HDCP_CAPABLE (0x1 << 1)
-#define DP_RXCAPS_REPEATER (0x1 << 0)
-#define DP_RXCAPS_HDCP_VERSION_2 (0x2)
-
-/* RxInfo */
-#define DEPTH_SHIFT (9)
-#define DEPTH_MASK (0x7)
-#define DEV_COUNT_SHIFT (4)
-#define DEV_COUNT_MASK (0x1F)
-#define DEV_EXD_SHIFT (3)
-#define DEV_EXD_MASK (0x1)
-#define CASCADE_EXD_SHIFT (2)
-#define CASCADE_EXD_MASK (0x1)
-#define HDCP20_DOWN_SHIFT (1)
-#define HDCP20_DOWN_MASK (0x1)
-#define HDCP1X_DOWN_SHIFT (0)
-#define HDCP1X_DOWN_MASK (0x1)
-
-#define dp_check_received_msg(m, m_len, len) \
- ((m == NULL) ? ERR_WRONG_BUFFER : \
- ((m_len < len) ? ERR_WRONG_MESSAGE_LENGTH : 0))
-
-int dp_cap_protocol_msg(uint8_t msg_id,
- uint8_t *msg,
- size_t *msg_len,
- struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx);
-
-int dp_decap_protocol_msg(uint8_t msg_id,
- uint8_t *msg,
- size_t msg_len,
- struct hdcp_tx_ctx *tx_ctx,
- struct hdcp_rx_ctx *rx_ctx);
-
-#endif
diff --git a/exynos-hdcp2-dplink-reg.h b/exynos-hdcp2-dplink-reg.h
deleted file mode 100644
index 42fb404..0000000
--- a/exynos-hdcp2-dplink-reg.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/* driver/soc/samsung/exynos-hdcp/dplink/exynos-hdcp2-dplink-reg.h
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-#ifndef __EXYNOS_HDCP2_DPLINK_REG_H__
-#define __EXYNOS_HDCP2_DPLINK_REG_H__
-
-#define DPCD_PACKET_SIZE (8)
-
-#define DPCD_ADDR_HDCP13_Bksv 0x68000
-#define DPCD_ADDR_HDCP13_Ri_prime 0x68005
-#define DPCD_ADDR_HDCP13_Aksv 0x68007
-#define DPCD_ADDR_HDCP13_An 0x6800C
-#define DPCD_ADDR_HDCP13_Vprime 0x68014
-#define DPCD_ADDR_HDCP13_Bcaps 0x68028
-#define DPCD_ADDR_HDCP13_Bstatus 0x68029
-#define DPCD_ADDR_HDCP13_Binfo 0x6802A
-#define DPCD_ADDR_HDCP13_Ksv_fifo 0x6802C
-#define DPCD_ADDR_HDCP22_Rtx 0x69000
-#define DPCD_ADDR_HDCP22_TxCaps 0x69008
-#define DPCD_ADDR_HDCP22_cert_rx 0x6900B
-#define DPCD_ADDR_HDCP22_Rrx 0x69215
-#define DPCD_ADDR_HDCP22_RxCaps 0x6921D
-#define DPCD_ADDR_HDCP22_Ekpub_km 0x69220
-#define DPCD_ADDR_HDCP22_Ekh_km_w 0x692A0
-#define DPCD_ADDR_HDCP22_m 0x692B0
-#define DPCD_ADDR_HDCP22_Hprime 0x692C0
-#define DPCD_ADDR_HDCP22_Ekh_km_r 0x692E0
-#define DPCD_ADDR_HDCP22_rn 0x692F0
-#define DPCD_ADDR_HDCP22_Lprime 0x692F8
-#define DPCD_ADDR_HDCP22_Edkey0_ks 0x69318
-#define DPCD_ADDR_HDCP22_Edkey1_ks 0x69320
-#define DPCD_ADDR_HDCP22_riv 0x69328
-#define DPCD_ADDR_HDCP22_RxInfo 0x69330
-#define DPCD_ADDR_HDCP22_seq_num_V 0x69332
-#define DPCD_ADDR_HDCP22_Vprime 0x69335
-#define DPCD_ADDR_HDCP22_Rec_ID_list 0x69345
-#define DPCD_ADDR_HDCP22_V 0x693E0
-#define DPCD_ADDR_HDCP22_seq_num_M 0x693F0
-#define DPCD_ADDR_HDCP22_k 0x693F3
-#define DPCD_ADDR_HDCP22_stream_IDtype 0x693F5
-#define DPCD_ADDR_HDCP22_Mprime 0x69473
-#define DPCD_ADDR_HDCP22_RxStatus 0x69493
-#define DPCD_ADDR_HDCP22_Type 0x69494
-
-#endif
diff --git a/exynos-hdcp2-dplink.c b/exynos-hdcp2-dplink.c
deleted file mode 100644
index bbdb7b9..0000000
--- a/exynos-hdcp2-dplink.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * drivers/soc/samsung/exynos-hdcp/dp_link/exynos-hdcp2-dplink.c
- *
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-#include <linux/smc.h>
-#include <asm/cacheflush.h>
-#include <linux/soc/samsung/exynos-smc.h>
-#include <linux/types.h>
-#include <linux/delay.h>
-
-#include "exynos-hdcp2.h"
-#include "exynos-hdcp2-log.h"
-#include "exynos-hdcp2-dplink.h"
-#include "exynos-hdcp2-dplink-if.h"
-#include "exynos-hdcp2-dplink-auth.h"
-#include "exynos-hdcp2-dplink-inter.h"
-#include "exynos-hdcp2-teeif.h"
-
-#define HDCP_AUTH_RETRY_COUNT 5
-#define RECVID_WAIT_RETRY_COUNT 5
-
-static DEFINE_MUTEX(hdcp_auth_mutex);
-/* current link data */
-static struct hdcp_link_data *lk_data;
-
-extern uint8_t rp_ready;
-extern enum auth_state auth_proc_state;
-static struct hdcp_sess_info ss_info;
-static struct hdcp_link_info lk_info;
-
-int hdcp_dplink_get_rxinfo(uint8_t *status)
-{
- int ret = 0;
-
- ret = hdcp_dplink_recv(HDCP22_MSG_RXSTATUS_R, status, sizeof(uint8_t));
- hdcp_info("RxStatus: %x\n", *status);
-
- return ret;
-}
-
-int do_dplink_auth(struct hdcp_link_info *lk_handle)
-{
- struct hdcp_session_node *ss_node;
- struct hdcp_link_node *lk_node;
- int ret = HDCP_SUCCESS;
- int rval = TX_AUTH_SUCCESS;
- uint32_t retry_recvid = 0;
- int hdcp_enabled = 0;
-
- /* find Session node which contains the Link */
-
- if (!rp_ready) {
- ss_node = hdcp_session_list_find(lk_handle->ss_id);
- if (!ss_node)
- return HDCP_ERROR_INVALID_INPUT;
-
- lk_node = hdcp_link_list_find(lk_handle->lk_id, &ss_node->ss_data->ln);
- if (!lk_node)
- return HDCP_ERROR_INVALID_INPUT;
-
- lk_data = lk_node->lk_data;
- if (!lk_data)
- return HDCP_ERROR_INVALID_INPUT;
-
- if (lk_data->state != LINK_ST_H1_TX_LOW_VALUE_CONTENT)
- return HDCP_ERROR_INVALID_STATE;
- }
- /**
- * if Upstream Content Control Function call this API,
- * it changes state to ST_A0_DETERMINE_RX_HDCP_CAP automatically.
- * HDCP library do not check CP desire.
- */
-
- if (!lk_data) {
- hdcp_info("DP HDCP2.2 Session is not opened.\n");
- return HDCP_ERROR_INVALID_INPUT;
- }
-
- if (rp_ready)
- UPDATE_LINK_STATE(lk_data, LINK_ST_A7_VERIFY_RECEIVER_ID_LIST);
- else
- UPDATE_LINK_STATE(lk_data, LINK_ST_A0_DETERMINE_RX_HDCP_CAP);
-
- do {
- switch (lk_data->state) {
- case LINK_ST_H1_TX_LOW_VALUE_CONTENT:
- hdcp_dplink_config(DP_HDCP22_DISABLE);
- return ret;
- case LINK_ST_A0_DETERMINE_RX_HDCP_CAP:
- if (dplink_determine_rx_hdcp_cap(lk_data) < 0) {
- ret = HDCP_ERROR_RX_NOT_HDCP_CAPABLE;
- UPDATE_LINK_STATE(lk_data, LINK_ST_H1_TX_LOW_VALUE_CONTENT);
- } else
- UPDATE_LINK_STATE(lk_data, LINK_ST_A1_EXCHANGE_MASTER_KEY);
- break;
- case LINK_ST_A1_EXCHANGE_MASTER_KEY:
- rval = dplink_exchange_master_key(lk_data);
- if (rval == TX_AUTH_SUCCESS) {
- UPDATE_LINK_STATE(lk_data, LINK_ST_A2_LOCALITY_CHECK);
- } else {
- /* todo: consider connection retry */
- ret = HDCP_ERROR_EXCHANGE_KM;
- UPDATE_LINK_STATE(lk_data, LINK_ST_H1_TX_LOW_VALUE_CONTENT);
- }
- break;
- case LINK_ST_A2_LOCALITY_CHECK:
- rval = dplink_locality_check(lk_data);
- if (rval == TX_AUTH_SUCCESS) {
- UPDATE_LINK_STATE(lk_data, LINK_ST_A3_EXCHANGE_SESSION_KEY);
- } else {
- /* todo: consider connection retry */
- ret = HDCP_ERROR_LOCALITY_CHECK;
- UPDATE_LINK_STATE(lk_data, LINK_ST_H1_TX_LOW_VALUE_CONTENT);
- }
- break;
- case LINK_ST_A3_EXCHANGE_SESSION_KEY:
- if (dplink_exchange_session_key(lk_data) < 0) {
- ret = HDCP_ERROR_EXCHANGE_KS;
- UPDATE_LINK_STATE(lk_data, LINK_ST_H1_TX_LOW_VALUE_CONTENT);
- } else {
- UPDATE_LINK_STATE(lk_data, LINK_ST_A4_TEST_REPEATER);
- }
- break;
- case LINK_ST_A4_TEST_REPEATER:
- if (dplink_evaluate_repeater(lk_data) == TRUE) {
- /* if it is a repeater, verify Rcv ID list */
- UPDATE_LINK_STATE(lk_data, LINK_ST_A6_WAIT_RECEIVER_ID_LIST);
- hdcp_info("It`s repeater link !\n");
- hdcp_enabled = 0;
- } else {
- /* if it is not a repeater, complete authentication */
- UPDATE_LINK_STATE(lk_data, LINK_ST_A5_AUTHENTICATED);
- hdcp_info("It`s Rx link !\n");
- hdcp_enabled = 1;
- }
- break;
- case LINK_ST_A5_AUTHENTICATED:
- /* HDCP2.2 spec defined 200ms */
- msleep(200);
- if (hdcp_enabled)
- hdcp_dplink_config(DP_HDCP22_ENABLE);
- /* Transmitter has completed the authentication protocol */
- ret = hdcp_tee_enable_enc_22();
- return HDCP_SUCCESS;
- case LINK_ST_A6_WAIT_RECEIVER_ID_LIST:
- rval = dplink_wait_for_receiver_id_list(lk_data);
- if (rval == -TX_AUTH_ERROR_TIME_EXCEED) {
- if (retry_recvid < RECVID_WAIT_RETRY_COUNT) {
- /* retry hdcp authentication in case of timeout */
- hdcp_dplink_config(DP_HDCP22_DISABLE);
- UPDATE_LINK_STATE(lk_data, LINK_ST_A0_DETERMINE_RX_HDCP_CAP);
- hdcp_info("retry authentication. (%d)\n", retry_recvid);
- retry_recvid++;
- } else {
- hdcp_info("exceed retry count. (%d)\n", retry_recvid);
- ret = HDCP_ERROR_VERIFY_RECEIVER_ID_LIST;
- UPDATE_LINK_STATE(lk_data, LINK_ST_H1_TX_LOW_VALUE_CONTENT);
- }
- } else if (rval == HDCP_SUCCESS) {
- UPDATE_LINK_STATE(lk_data, LINK_ST_A7_VERIFY_RECEIVER_ID_LIST);
- retry_recvid = 0;
- } else {
- /* error on recevier id list wait */
- ret = HDCP_ERROR_VERIFY_RECEIVER_ID_LIST;
- UPDATE_LINK_STATE(lk_data, LINK_ST_H1_TX_LOW_VALUE_CONTENT);
- }
- break;
- case LINK_ST_A7_VERIFY_RECEIVER_ID_LIST:
- if (dplink_verify_receiver_id_list(lk_data) < 0) {
- ret = HDCP_ERROR_VERIFY_RECEIVER_ID_LIST;
- UPDATE_LINK_STATE(lk_data, LINK_ST_H1_TX_LOW_VALUE_CONTENT);
- } else {
- UPDATE_LINK_STATE(lk_data, LINK_ST_A8_SEND_RECEIVER_ID_LIST_ACK);
- }
- break;
- case LINK_ST_A8_SEND_RECEIVER_ID_LIST_ACK:
- rval = dplink_send_receiver_id_list_ack(lk_data);
- if (rval < 0) {
- ret = HDCP_ERROR_VERIFY_RECEIVER_ID_LIST;
- UPDATE_LINK_STATE(lk_data, LINK_ST_H1_TX_LOW_VALUE_CONTENT);
- } else {
- UPDATE_LINK_STATE(lk_data, LINK_ST_A9_CONTENT_STREAM_MGT);
- }
- break;
- case LINK_ST_A9_CONTENT_STREAM_MGT:
- rval = dplink_stream_manage(lk_data);
- if (rval < 0) {
- ret = HDCP_ERROR_STREAM_MANAGE;
- UPDATE_LINK_STATE(lk_data, LINK_ST_H1_TX_LOW_VALUE_CONTENT);
- } else {
- UPDATE_LINK_STATE(lk_data, LINK_ST_A5_AUTHENTICATED);
- auth_proc_state = HDCP2_AUTH_PROCESS_DONE;
- }
- break;
- default:
- ret = HDCP_ERROR_INVALID_STATE;
- UPDATE_LINK_STATE(lk_data, LINK_ST_H1_TX_LOW_VALUE_CONTENT);
- break;
- }
- } while (1);
-}
-
-/* todo: support multi link & multi session */
-int hdcp_dplink_authenticate(void)
-{
- int ret;
- static int retry_cnt;
-
- mutex_lock(&hdcp_auth_mutex);
- auth_proc_state = HDCP_AUTH_PROCESS_IDLE;
- for (; retry_cnt < HDCP_AUTH_RETRY_COUNT; retry_cnt++) {
- if (!rp_ready) {
- hdcp_clear_session(ss_info.ss_id);
- if (hdcp_session_open(&ss_info)) {
- mutex_unlock(&hdcp_auth_mutex);
- return -ENOMEM;
- }
-
- lk_info.ss_id = ss_info.ss_id;
- if (hdcp_link_open(&lk_info, HDCP_LINK_TYPE_DP)) {
- hdcp_session_close(&ss_info);
- mutex_unlock(&hdcp_auth_mutex);
- return -ENOMEM;
- }
-
- /* if hdcp is enabled, disable it while hdcp authentication */
- if (hdcp_dplink_is_enabled_hdcp22())
- hdcp_dplink_config(DP_HDCP22_DISABLE);
-
- dplink_clear_irqflag_all();
- }
-
- ret = do_dplink_auth(&lk_info);
- if (ret == HDCP_SUCCESS) {
- hdcp_info("Success HDCP authenticate done.\n");
- retry_cnt = 0;
- mutex_unlock(&hdcp_auth_mutex);
- return 0;
- } else {
- /* auth_proc_state flag check */
- if (auth_proc_state == HDCP_AUTH_PROCESS_STOP) {
- hdcp_info("Stop authenticate.\n");
- auth_proc_state = HDCP_AUTH_PROCESS_IDLE;
- break;
- }
- /* retry */
- dplink_clear_irqflag_all();
- hdcp_err("HDCP auth failed. retry(%d)\n", retry_cnt);
- }
- }
-
- retry_cnt = 0;
- mutex_unlock(&hdcp_auth_mutex);
- return -EACCES;
-}
-
-void hdcp_clear_session(uint32_t id)
-{
- struct hdcp_sess_info ss;
- struct hdcp_link_info lk;
-
- ss.ss_id = id;
- lk.ss_id = id;
- lk.lk_id = id;
- hdcp_link_close(&lk);
- hdcp_session_close(&ss);
-}
-
-int hdcp_dplink_stream_manage(void)
-{
- hdcp_info("stream manage updated.\n");
- /* todo: update stream manage information */
- return 0;
-}
diff --git a/exynos-hdcp2-dplink.h b/exynos-hdcp2-dplink.h
deleted file mode 100644
index b7385db..0000000
--- a/exynos-hdcp2-dplink.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* driver/soc/samsung/exynos-hdcp/dplink/exynos-hdcp2-dplink.h
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-#ifndef __EXYNOS_HDCP2_DPLINK_H__
-#define __EXYNOS_HDCP2_DPLINK_H__
-
-#include "exynos-hdcp2.h"
-
-enum auth_signal {
- HDCP_OFF = 0x100,
- HDCP1_ON = 0x200,
- HDCP2_ON = 0x300,
-};
-
-enum drm_state {
- DRM_OFF = 0x0,
- DRM_ON = 0x1,
- DRM_SAME_STREAM_TYPE = 0x2 /* If the previous contents and stream_type id are the same flag */
-};
-
-/* Do hdcp2.2 authentication with DP Receiver
- * and enable encryption if authentication is succeed.
- * @return
- * - 0: Success
- * - ENOMEM: hdcp context open fail
- * - EACCES: authentication fail
- */
-int hdcp_dplink_get_rxinfo(uint8_t *status);
-int hdcp_dplink_authenticate(void);
-int do_dplink_auth(struct hdcp_link_info *lk_handle);
-void hdcp_clear_session(uint32_t id);
-#endif
diff --git a/exynos-hdcp2-main.c b/exynos-hdcp2-main.c
deleted file mode 100644
index 3d0a350..0000000
--- a/exynos-hdcp2-main.c
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * drivers/soc/samsung/exynos-hdcp/exynos-hdcp.c
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-#include <linux/smc.h>
-#include <asm/cacheflush.h>
-#include <linux/soc/samsung/exynos-smc.h>
-#include "exynos-hdcp2-teeif.h"
-#include "exynos-hdcp2-log.h"
-#include "exynos-hdcp2-dplink-if.h"
-#include "exynos-hdcp2-dplink.h"
-#include "exynos-hdcp2-dplink-inter.h"
-#include "exynos-hdcp2-selftest.h"
-#include <linux/of_irq.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/irqreturn.h>
-#include <linux/dma-mapping.h>
-
-#define EXYNOS_HDCP_DEV_NAME "hdcp2"
-
-static struct miscdevice hdcp;
-struct device *device_hdcp;
-static DEFINE_MUTEX(hdcp_lock);
-extern enum dp_state dp_hdcp_state;
-
-struct hdcp_ctx {
- struct delayed_work work;
- /* debugfs root */
- struct dentry *debug_dir;
- /* seclog can be disabled via debugfs */
- bool enabled;
- unsigned int irq;
-};
-
-static struct hdcp_ctx h_ctx;
-static uint32_t inst_num;
-
-static ssize_t hdcp_write(struct file *file, const char __user *buf,
- size_t len, loff_t *ppos)
-{
- hdcp_info("Kicking off selftest\n");
- dp_hdcp_protocol_self_test();
- return len;
-}
-
-static ssize_t hdcp_read(struct file *filp, char __user *buf,
- size_t count, loff_t *f_pos)
-{
- return 0;
-}
-
-static int hdcp_open(struct inode *inode, struct file *file)
-{
- struct miscdevice *miscdev = file->private_data;
- struct device *dev = miscdev->this_device;
- struct hdcp_info *info;
-
- info = kzalloc(sizeof(struct hdcp_info), GFP_KERNEL);
- if (!info)
- return -ENOMEM;
-
- info->dev = dev;
- file->private_data = info;
-
- mutex_lock(&hdcp_lock);
- inst_num++;
- /* todo: hdcp device initialize ? */
- mutex_unlock(&hdcp_lock);
-
- return 0;
-}
-
-static int hdcp_release(struct inode *inode, struct file *file)
-{
- struct hdcp_info *info = file->private_data;
-
- /* disable drm if we were the one to turn it on */
- mutex_lock(&hdcp_lock);
- inst_num--;
- /* todo: hdcp device finalize ? */
- mutex_unlock(&hdcp_lock);
-
- kfree(info);
- return 0;
-}
-
-static void exynos_hdcp_worker(struct work_struct *work)
-{
- if (dp_hdcp_state == DP_DISCONNECT) {
- hdcp_err("dp_disconnected\n");
- return;
- }
-
- hdcp_info("Exynos HDCP interrupt occur by LDFW.\n");
- hdcp_dplink_auth_control(HDCP2_ON);
-}
-
-static irqreturn_t exynos_hdcp_irq_handler(int irq, void *dev_id)
-{
- if (h_ctx.enabled) {
- schedule_delayed_work(&h_ctx.work, msecs_to_jiffies(0));
- }
-
- return IRQ_HANDLED;
-}
-
-static int exynos_hdcp_probe(struct platform_device *pdev)
-{
- int err;
-
- h_ctx.irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
- if (!h_ctx.irq) {
- dev_err(&pdev->dev, "Fail to get irq from dt\n");
- return -EINVAL;
- }
-
- /* Get hardware interrupt number */
- err = devm_request_irq(&pdev->dev, h_ctx.irq,
- exynos_hdcp_irq_handler,
- IRQF_TRIGGER_RISING, pdev->name, NULL);
-
- device_hdcp = &pdev->dev;
-
-// arch_setup_dma_ops(&pdev->dev, 0x0ULL, 1ULL << 36, NULL, false);
- pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
- dma_set_mask(&pdev->dev, DMA_BIT_MASK(36));
-
- if (err) {
- dev_err(&pdev->dev,
- "Fail to request IRQ handler. err(%d) irq(%d)\n",
- err, h_ctx.irq);
- return err;
- }
- /* Set workqueue for Secure log as bottom half */
- INIT_DELAYED_WORK(&h_ctx.work, exynos_hdcp_worker);
- h_ctx.enabled = true;
-
- hdcp_info("Exynos HDCP driver probe done! (%d)\n", err);
- return err;
-}
-
-static const struct of_device_id exynos_hdcp_of_match_table[] = {
- { .compatible = "samsung,exynos-hdcp", },
- { },
-};
-
-static struct platform_driver exynos_hdcp_driver = {
- .probe = exynos_hdcp_probe,
- .driver = {
- .name = "exynos-hdcp",
- .owner = THIS_MODULE,
- .of_match_table = of_match_ptr(exynos_hdcp_of_match_table),
- }
-};
-
-static int __init hdcp_init(void)
-{
- int ret;
-
- hdcp_info("hdcp2 driver init\n");
-
- ret = misc_register(&hdcp);
- if (ret) {
- hdcp_err("hdcp can't register misc on minor=%d\n",
- MISC_DYNAMIC_MINOR);
- return ret;
- }
-
- hdcp_session_list_init();
- hdcp_tee_init();
-
- return platform_driver_register(&exynos_hdcp_driver);
-}
-
-static void __exit hdcp_exit(void)
-{
- /* todo: do clear sequence */
- cancel_delayed_work_sync(&h_ctx.work);
-
- misc_deregister(&hdcp);
- hdcp_session_list_destroy();
- hdcp_tee_close();
- platform_driver_unregister(&exynos_hdcp_driver);
-}
-
-static const struct file_operations hdcp_fops = {
- .owner = THIS_MODULE,
- .write = hdcp_write,
- .read = hdcp_read,
- .open = hdcp_open,
- .release = hdcp_release,
-};
-
-static struct miscdevice hdcp = {
- .minor = MISC_DYNAMIC_MINOR,
- .name = EXYNOS_HDCP_DEV_NAME,
- .fops = &hdcp_fops,
-};
-
-module_init(hdcp_init);
-module_exit(hdcp_exit);
-
-MODULE_DESCRIPTION("Exynos Secure hdcp driver");
-MODULE_AUTHOR("<hakmin_1.kim@samsung.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/exynos-hdcp2-protocol-msg.c b/exynos-hdcp2-protocol-msg.c
deleted file mode 100644
index e87f151..0000000
--- a/exynos-hdcp2-protocol-msg.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * drivers/soc/samsung/exynos-hdcp/exynos-hdcp2-protocol-msg.c
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/kernel.h>
-
-#include "exynos-hdcp2-protocol-msg.h"
-#include "exynos-hdcp2-teeif.h"
-#include "exynos-hdcp2.h"
-#include "exynos-hdcp2-log.h"
-#include "exynos-hdcp2-dplink-protocol-msg.h"
-
-int ske_generate_sessionkey(uint32_t lk_type, uint8_t *enc_skey, int share_skey)
-{
- int ret;
-
- ret = teei_generate_skey(lk_type,
- enc_skey, HDCP_SKE_SKEY_LEN,
- share_skey);
- if (ret) {
- hdcp_err("generate_session_key() is failed with %x\n", ret);
- return ERR_GENERATE_SESSION_KEY;
- }
-
- return 0;
-}
-
-int ske_generate_riv(uint8_t *out)
-{
- int ret;
-
- ret = teei_generate_riv(out, HDCP_RTX_BYTE_LEN);
- if (ret) {
- hdcp_err("teei_generate_riv() is failed with %x\n", ret);
- return ERR_GENERATE_NON_SECKEY;
- }
-
- return 0;
-}
-
-int lc_generate_rn(uint8_t *out, size_t out_len)
-{
- int ret;
-
- ret = teei_gen_rn(out, out_len);
- if (ret) {
- hdcp_err("lc_generate_rn() is failed with %x\n", ret);
- return ERR_GENERATE_NON_SECKEY;
- }
-
- return 0;
-}
-
-int lc_compare_hmac(uint8_t *rx_hmac, size_t hmac_len)
-{
- int ret;
-
- ret = teei_compare_lc_hmac(rx_hmac, hmac_len);
- if (ret) {
- hdcp_err("compare_lc_hmac_val() is failed with %x\n", ret);
- return ERR_COMPARE_LC_HMAC;
- }
-
- return ret;
-}
-
-int ake_verify_cert(uint8_t *cert, size_t cert_len,
- uint8_t *rrx, size_t rrx_len,
- uint8_t *rx_caps, size_t rx_caps_len)
-{
- int ret;
-
- ret = teei_verify_cert(cert, cert_len,
- rrx, rrx_len,
- rx_caps, rx_caps_len);
- if (ret) {
- hdcp_err("teei_verify_cert() is failed with %x\n", ret);
- return ERR_VERIFY_CERT;
- }
-
- return 0;
-}
-
-int ake_generate_masterkey(uint32_t lk_type, uint8_t *enc_mkey, size_t elen)
-{
- int ret;
-
- /* Generate Encrypted & Wrapped Master Key */
- ret = teei_generate_master_key(lk_type, enc_mkey, elen);
- if (ret) {
- hdcp_err("generate_master_key() is failed with %x\n", ret);
- return ERR_GENERATE_MASTERKEY;
- }
-
- return ret;
-}
-
-int ake_compare_hmac(uint8_t *rx_hmac, size_t rx_hmac_len)
-{
- int ret;
-
- ret = teei_compare_ake_hmac(rx_hmac, rx_hmac_len);
- if (ret) {
- hdcp_err("teei_compare_hmac() is failed with %x\n", ret);
- return ERR_COMPUTE_AKE_HMAC;
- }
-
- return 0;
-}
-
-int ake_store_master_key(uint8_t *ekh_mkey, size_t ekh_mkey_len)
-{
- int ret;
-
- ret = teei_set_pairing_info(ekh_mkey, ekh_mkey_len);
- if (ret) {
- hdcp_err("teei_store_pairing_info() is failed with %x\n", ret);
- return ERR_STORE_MASTERKEY;
- }
-
- return 0;
-}
-
-int ake_find_masterkey(int *found_km,
- uint8_t *ekh_mkey, size_t ekh_mkey_len,
- uint8_t *m, size_t m_len)
-{
- int ret;
-
- ret = teei_get_pairing_info(ekh_mkey, ekh_mkey_len, m, m_len, found_km);
- if (ret) {
- *found_km = 0;
- hdcp_err("teei_store_pairing_info() is failed with %x\n", ret);
- return ERR_FIND_MASTERKEY;
- }
-
- return 0;
-}
diff --git a/exynos-hdcp2-protocol-msg.h b/exynos-hdcp2-protocol-msg.h
deleted file mode 100644
index 80f6bca..0000000
--- a/exynos-hdcp2-protocol-msg.h
+++ /dev/null
@@ -1,217 +0,0 @@
-/* drivers/soc/samsung/exynos-hdcp/exynos-hdcp2-protocol-msg.h
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef __EXYNOS_HDCP2_PROTOCOL_MSG_H__
-#define __EXYNOS_HDCP2_PROTOCOL_MSG_H__
-
-#include <linux/types.h>
-#include "exynos-hdcp2-teeif.h"
-
-/* Error */
-#define ERR_TLC_CONNECT 0x1001
-#define ERR_WRONG_BUFFER 0x1002
-#define ERR_WRONG_MESSAGE_LENGTH 0x1003
-#define ERR_WRONG_MESSAGE_ID 0x1004
-#define ERR_GENERATE_NON_SECKEY 0x1005
-#define ERR_FILE_OPEN 0x1006
-
-#define ERR_GENERATE_RTX 0x2001
-#define ERR_VERIFY_CERT 0x2002
-#define ERR_GENERATE_MASTERKEY 0x2003
-#define ERR_COMPUTE_AKE_HMAC 0x2004
-#define ERR_COMPARE_AKE_HMAC 0x2005
-#define ERR_STORE_MASTERKEY 0x2006
-#define ERR_CHECK_SRM 0x2007
-#define ERR_WRAP_SRM 0x2008
-#define ERR_SET_INFO 0x2009
-#define ERR_MEMORY_ALLOCATION 0x200A
-#define ERR_GET_TX_INFO 0x200B
-#define ERR_SET_RX_INFO 0x200C
-#define ERR_SET_RRX 0x200D
-#define ERR_FIND_MASTERKEY 0x200E
-
-#define ERR_GENERATE_RN 0x3001
-#define ERR_COMPUTE_LC_HMAC 0x3002
-#define ERR_COMPARE_LC_HMAC 0x3003
-
-#define ERR_GENERATE_RIV 0x4001
-#define ERR_GENERATE_SESSION_KEY 0x4002
-
-#define ERR_HDCP_ENCRYPTION 0x5001
-
-#define ERR_RP_VERIFY_RCVLIST 0x6001
-#define ERR_EXCEED_MAX_STREAM 0x6002
-#define ERR_VALIDATE_M 0x6003
-#define ERR_SEND_ACK 0x6004
-#define ERR_RP_GEN_STREAM_MG 0x6005
-#define ERR_RP_INVALID_M_PRIME 0x6006
-
-#define HDCP_RP_RCV_LIST_PRE_META_LEN 2
-#define HDCP_RP_RCV_LIST_META_LEN 23
-
-#define HDCP_PROTO_MSG_ID_LEN 1
-#define HDCP_TX_REPEATER_MAX_STREAM 32
-#define STREAM_ELEM_SIZE 5
-#define STREAM_INFO_SIZE 7
-#define STREAM_MAX_LEN 1024
-
-enum {
- HDCP_VERSION_2_0 = 0x00,
- HDCP_VERSION_2_1 = 0x01,
- HDCP_VERSION_2_2 = 0x01,
-};
-
-enum {
- LC_PRECOMPUTE_NOT_SUPPORT = 0x00,
- LC_PRECOMPUTE_SUPPORT = 0x01,
-};
-
-enum msg_id {
- AKE_INIT = 2,
- AKE_SEND_CERT,
- AKE_NO_STORED_KM,
- AKE_STORED_KM,
- AKE_SEND_RRX,
- AKE_SEND_H_PRIME,
- AKE_SEND_PAIRING_INFO,
- LC_INIT,
- LC_SEND_L_PRIME,
- SKE_SEND_EKS,
- REPEATERAUTH_SEND_RECEIVERID_LIST,
- RTT_READY,
- RTT_CHALLENGE,
- REPEATERAUTH_SEND_ACK,
- REPEATERAUTH_STREAM_MANAGE,
- REPEATERAUTH_STREAM_READY,
- RECEIVER_AUTHSTATUS,
- AKE_TRANSMITTER_INFO,
- AKE_RECEIVER_INFO,
-};
-
-struct stream_info {
- uint8_t type;
- uint16_t pid;
- uint32_t ctr;
-};
-
-struct contents_info {
- uint8_t str_num;
- struct stream_info str_info[HDCP_TX_REPEATER_MAX_STREAM];
-};
-
-struct hdcp_rpauth_info {
- uint8_t devs_exd;
- uint8_t cascade_exd;
- uint8_t devs_count;
- uint8_t depth;
- uint8_t hdcp2_down;
- uint8_t hdcp1_down;
- uint8_t rx_info[HDCP_RP_RX_INFO_LEN];
- uint8_t seq_num_v[HDCP_RP_SEQ_NUM_V_LEN];
- uint8_t v_prime[HDCP_RP_HMAC_V_LEN / 2];
- union {
- uint8_t arr[HDCP_RCV_DEVS_COUNT_MAX][HDCP_RCV_ID_LEN];
- uint8_t lst[HDCP_RP_RCVID_LIST_LEN];
- } u_rcvid;
- /* repeater auth result */
- uint8_t v[HDCP_RP_HMAC_V_LEN / 2];
- uint8_t valid;
-};
-
-struct dp_stream_info {
- uint16_t stream_num;
- uint8_t streamid[HDCP_RP_MAX_STREAMID_NUM];
- uint8_t seq_num_m[HDCP_RP_SEQ_NUM_M_LEN];
- uint8_t k[HDCP_RP_K_LEN];
- uint8_t streamid_type[HDCP_RP_MAX_STREAMID_TYPE_LEN];
-};
-
-union stream_manage {
- struct dp_stream_info dp;
- /* todo: add IIA */
-};
-
-struct hdcp_tx_ctx {
- uint8_t version;
- uint8_t lc_precomp;
-
- /* master key */
- uint8_t wrap_mkey[HDCP_AKE_WKEY_BYTE_LEN];
- uint8_t caps[HDCP_CAPS_BYTE_LEN];
- uint8_t ekh_mkey[HDCP_AKE_EKH_MKEY_BYTE_LEN];
- uint8_t m[HDCP_AKE_M_BYTE_LEN];
-
- uint8_t rtx[HDCP_AKE_RTX_BYTE_LEN];
- uint8_t rn[HDCP_AKE_RTX_BYTE_LEN];
- uint8_t riv[HDCP_AKE_RTX_BYTE_LEN];
- uint8_t lsb16_hmac[HDCP_HMAC_SHA256_LEN / 2];
-
- /* session key */
- uint8_t str_ctr[HDCP_STR_CTR_LEN];
- uint8_t input_ctr[HDCP_INPUT_CTR_LEN];
-
- /* receiver list */
- struct hdcp_rpauth_info rpauth_info;
-
- /* stream manage info */
- union stream_manage strm;
-
- /* repeater reauth request */
- uint8_t rp_reauth;
-
- /* todo: move stream_ctrl */
- struct contents_info stream_ctrl;
-
- int share_skey;
- uint32_t seq_num_M;
- uint8_t strmsg[HDCP_TX_REPEATER_MAX_STREAM * 8];
- size_t strmsg_len;
-};
-
-struct hdcp_rx_ctx {
- uint8_t version;
- uint8_t lc_precomp;
- uint8_t repeater;
- uint8_t caps[HDCP_CAPS_BYTE_LEN]; /* only for DP */
- uint8_t receiver_id[RECEIVER_ID_BYTE_LEN];
- uint8_t rrx[HDCP_AKE_RTX_BYTE_LEN];
- uint8_t cert[HDCP_RX_CERT_LEN];
-};
-
-int ake_find_masterkey(int *found_km,
- uint8_t *ekh_mkey, size_t ekh_mkey_len,
- uint8_t *m, size_t m_len);
-
-#define check_received_msg(m, m_len, len, func_id) \
- ((m == NULL) ? ERR_WRONG_BUFFER : \
- ((m_len < len) ? ERR_WRONG_MESSAGE_LENGTH : \
- ((m[0] != func_id) ? ERR_WRONG_MESSAGE_ID : 0)))
-
-#endif
-
-int ake_verify_cert(uint8_t *cert, size_t cert_len,
- uint8_t *rrx, size_t rrx_len,
- uint8_t *rx_caps, size_t rx_caps_len);
-int ake_generate_masterkey(uint32_t lk_type,
- uint8_t *enc_mkey, size_t elen);
-int ake_make_hmac(uint8_t *whmac, uint8_t *wrap_mkey,
- uint8_t *rtx, uint8_t repeater,
- uint8_t *hmac_append);
-int ake_make_hmac_with_caps(uint8_t *whmac, uint8_t *wrap_mkey,
- uint8_t *rtx, uint8_t *rrx,
- uint8_t *tx_caps, uint8_t *rx_caps);
-int ake_compare_hmac(uint8_t *rx_hmac, size_t rx_hmac_len);
-int ake_store_master_key(uint8_t *ekh_mkey, size_t ekh_mkey_len);
-
-int lc_generate_rn(uint8_t *out, size_t out_len);
-int lc_compare_hmac(uint8_t *rx_hmac, size_t hmac_len);
-
-int ske_generate_riv(uint8_t *out);
-int ske_generate_sessionkey(uint32_t lk_type, uint8_t *enc_skey,
- int share_skey);
diff --git a/exynos-hdcp2-selftest.h b/exynos-hdcp2-selftest.h
deleted file mode 100644
index ded6a1a..0000000
--- a/exynos-hdcp2-selftest.h
+++ /dev/null
@@ -1,13 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Platform device driver for HDCP selftest.
- *
- * Copyright (C) 2023 Google LLC
- */
-
-#ifndef __EXYNOS_HDCP2_DPLINK_SELFTEST_H__
-#define __EXYNOS_HDCP2_DPLINK_SELFTEST_H__
-
-int dp_hdcp_protocol_self_test(void);
-
-#endif
diff --git a/exynos-hdcp2-session.c b/exynos-hdcp2-session.c
deleted file mode 100644
index 0874ab0..0000000
--- a/exynos-hdcp2-session.c
+++ /dev/null
@@ -1,516 +0,0 @@
-/*
- * drivers/soc/samsung/exynos-hdcp/exynos-hdcp2-tx-session.c
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/slab.h>
-#include <linux/module.h>
-
-#include "exynos-hdcp2.h"
-#include "exynos-hdcp2-log.h"
-
-/**
- * generate data for a session data
- */
-
-static struct hdcp_session_list g_hdcp_session_list;
-static uint8_t session_wkey[HDCP_WRAP_MAX_SIZE];
-
-enum hdcp_result hdcp_session_open(struct hdcp_sess_info *ss_info)
-{
- struct hdcp_session_data *new_ss = NULL;
- struct hdcp_session_node *new_ss_node = NULL;
-
- /* do open session */
- new_ss_node = (struct hdcp_session_node *)kzalloc(sizeof(struct hdcp_session_node), GFP_KERNEL);
-
- if (!new_ss_node) {
- return HDCP_ERROR_INVALID_HANDLE;
- }
-
- new_ss = hdcp_session_data_create();
- if (!new_ss) {
- kfree(new_ss_node);
- return HDCP_ERROR_INVALID_HANDLE;
- }
-
- /* send session info to SWD */
- /* todo: add error check */
-
- UPDATE_SESSION_STATE(new_ss, SESS_ST_LINK_SETUP);
- ss_info->ss_id = new_ss->id;
- new_ss_node->ss_data = new_ss;
-
- hdcp_session_list_add((struct hdcp_session_node *)new_ss_node);
-
- memcpy(session_wkey, ss_info->wkey, HDCP_WRAP_MAX_SIZE);
-
- return HDCP_SUCCESS;
-}
-
-enum hdcp_result hdcp_session_close(struct hdcp_sess_info *ss_info)
-{
- struct hdcp_session_node *ss_node;
- struct hdcp_session_data *ss_data;
- uint32_t ss_handle;
-
- ss_handle = ss_info->ss_id;
-
- ss_node = hdcp_session_list_find(ss_handle);
- if (!ss_node) {
- return HDCP_ERROR_INVALID_HANDLE;
- }
-
- ss_data = ss_node->ss_data;
- if (ss_data->state != SESS_ST_LINK_SETUP)
- return HDCP_ERROR_INVALID_STATE;
-
- ss_handle = ss_info->ss_id;
- UPDATE_SESSION_STATE(ss_data, SESS_ST_END);
-
- hdcp_session_list_del(ss_node);
- hdcp_session_data_destroy(&(ss_node->ss_data));
-
- return HDCP_SUCCESS;
-}
-
-enum hdcp_result hdcp_link_open(struct hdcp_link_info *link_info, uint32_t lk_type)
-{
- struct hdcp_session_node *ss_node = NULL;
- struct hdcp_link_node *new_lk_node = NULL;
- struct hdcp_link_data *new_lk_data = NULL;
- int ret = HDCP_SUCCESS;
- uint32_t ss_handle;
-
- ss_handle = link_info->ss_id;
-
- do {
- /* find Session node which will contain new Link */
- ss_node = hdcp_session_list_find(ss_handle);
- if (!ss_node) {
- ret = HDCP_ERROR_INVALID_INPUT;
- break;
- }
-
- /* make a new link node and add it to the session */
- new_lk_node = (struct hdcp_link_node *)kzalloc(sizeof(struct hdcp_link_node), GFP_KERNEL);
- if (!new_lk_node) {
- ret = HDCP_ERROR_MALLOC_FAILED;
- break;
- }
- new_lk_data = hdcp_link_data_create();
- if (!new_lk_data) {
- ret = HDCP_ERROR_MALLOC_FAILED;
- break;
- }
-
- UPDATE_LINK_STATE(new_lk_data, LINK_ST_H0_NO_RX_ATTATCHED);
-
- new_lk_data->ss_ptr = ss_node;
- new_lk_data->lk_type = lk_type;
- new_lk_node->lk_data = new_lk_data;
-
- hdcp_link_list_add(new_lk_node, &ss_node->ss_data->ln);
-
- link_info->ss_id = ss_node->ss_data->id;
- link_info->lk_id = new_lk_data->id;
-
- } while (0);
-
- if (ret != HDCP_SUCCESS) {
- if (new_lk_node)
- kfree(new_lk_node);
- if (new_lk_data)
- hdcp_link_data_destroy(&new_lk_data);
-
- return HDCP_ERROR_LINK_OPEN_FAILED;
- }
- else
- UPDATE_LINK_STATE(new_lk_data, LINK_ST_H1_TX_LOW_VALUE_CONTENT);
-
- return HDCP_SUCCESS;
-}
-
-enum hdcp_result hdcp_link_close(struct hdcp_link_info *lk_info)
-{
- struct hdcp_session_node *ss_node = NULL;
- struct hdcp_link_node *lk_node = NULL;
-
- /* find Session node which contain the Link */
- ss_node = hdcp_session_list_find(lk_info->ss_id);
-
- if (!ss_node)
- return HDCP_ERROR_INVALID_INPUT;
-
- lk_node = hdcp_link_list_find(lk_info->lk_id, &ss_node->ss_data->ln);
- if (!lk_node)
- return HDCP_ERROR_INVALID_INPUT;
-
- UPDATE_LINK_STATE(lk_node->lk_data, LINK_ST_H0_NO_RX_ATTATCHED);
-
- hdcp_link_list_del(lk_node, &ss_node->ss_data->ln);
- hdcp_link_data_destroy(&(lk_node->lk_data));
-
- return HDCP_SUCCESS;
-}
-
-
-struct hdcp_session_data *hdcp_session_data_create(void)
-{
- struct hdcp_session_data *new_ss_data = NULL;
- static int count = 0; /* TODO change session id creation method */
-
- new_ss_data = (struct hdcp_session_data *)kzalloc(sizeof(struct hdcp_session_data), GFP_KERNEL);
- if (!new_ss_data) {
- return NULL;
- }
-
- /* init session data */
- new_ss_data->id = count++;
-
- new_ss_data->wrap_skey_store = WRAP_SKEY_EMPTY;
- memset(new_ss_data->riv, 0x00, sizeof(new_ss_data->riv));
- hdcp_link_list_init(&(new_ss_data->ln));
-
- new_ss_data->state = SESS_ST_INIT;
-
- return new_ss_data;
-}
-
-/**
- * destroy a session data
- */
-void hdcp_session_data_destroy(struct hdcp_session_data **ss_data)
-{
- if (!(*ss_data) || !ss_data)
- return;
-
- /* clear session key and riv */
- memset((*ss_data)->wrap_skey, 0x00, sizeof((*ss_data)->wrap_skey));
- memset((*ss_data)->riv, 0x00, sizeof((*ss_data)->riv));
- /* clear link list */
- hdcp_link_list_destroy(&((*ss_data)->ln));
-
- if (*ss_data) {
- kfree(*ss_data);
- *ss_data = NULL;
- }
-}
-
-/**
- * generate data for a link data
- */
-struct hdcp_link_data *hdcp_link_data_create(void)
-{
- struct hdcp_link_data *new_lk_data = NULL;
- static int count = 0; /* TODO: change link id creation method */
-
- new_lk_data = (struct hdcp_link_data *)kzalloc(sizeof(struct hdcp_link_data), GFP_KERNEL);
- if (!new_lk_data) {
- return NULL;
- }
-
- /* init link data */
- new_lk_data->id = count++;
- new_lk_data->state = LINK_ST_INIT;
-
- /* set HDCP version */
-#ifdef HDCP_TX_VERSION_2_2
- new_lk_data->tx_ctx.version = HDCP_VERSION_2_2;
-#endif
-
- return new_lk_data;
-}
-
-/**
- * destroy a link data
- */
-void hdcp_link_data_destroy(struct hdcp_link_data **lk_data)
-{
- if (!(*lk_data) || !lk_data)
- return;
-
- (*lk_data)->ss_ptr = NULL;
-
- if (*lk_data) {
- kfree(*lk_data);
- *lk_data = NULL;
- }
-}
-
-/**
- * init a Session list
- * @ss_list: list head to add it after
- */
-void hdcp_session_list_init(void)
-{
- struct hdcp_session_node *ss_head;
- struct hdcp_session_list *ss_list = &g_hdcp_session_list;
-
- /* hdcp session list mutex init */
- mutex_init(&ss_list->ss_mutex);
-
- ss_head = &(ss_list->hdcp_session_head);
- ss_head->next = ss_head;
- ss_head->prev = ss_head;
- ss_head->ss_data = NULL;
-}
-
-/**
- * add a new entry to the Session list
- * @new_ent: new entry to be added
- * @ss_list: list head to add it after
- *
- * Insert a new entry after the specified head
- */
-void hdcp_session_list_add(struct hdcp_session_node *new_ent)
-{
- struct hdcp_session_node *ss_head;
- struct hdcp_session_list *ss_list = &g_hdcp_session_list;
-
- if (!new_ent)
- return;
-
- mutex_lock(&(ss_list->ss_mutex));
- ss_head = &(ss_list->hdcp_session_head);
-
- ss_head->next->prev = new_ent;
- new_ent->next = ss_head->next;
-
- new_ent->prev = ss_head;
- ss_head->next = new_ent;
- mutex_unlock(&(ss_list->ss_mutex));
-
- return;
-
-}
-
-/**
- * delete a entry form the Session list
- * @del_ent: a entry to be deleted
- * @ss_list: session list to remove the session node
- */
-void hdcp_session_list_del(struct hdcp_session_node *del_ent)
-{
- struct hdcp_session_list *ss_list = &g_hdcp_session_list;
-
- if (!del_ent)
- return;
-
- mutex_lock(&ss_list->ss_mutex);
- del_ent->prev->next = del_ent->next;
- del_ent->next->prev = del_ent->prev;
- mutex_unlock(&ss_list->ss_mutex);
-}
-
-/**
- * print all entries in the Session list
- * @ss_list: session list to print all nodes
- */
-void hdcp_session_list_print_all(void)
-{
- struct hdcp_session_node *pos;
- struct hdcp_session_node *ss_head;
- struct hdcp_session_list *ss_list = &g_hdcp_session_list;
-
- mutex_lock(&ss_list->ss_mutex);
- ss_head = &(ss_list->hdcp_session_head);
- for (pos = ss_head->next; pos != ss_head && pos != NULL; pos = pos->next)
- hdcp_info("SessionID: %d\n", pos->ss_data->id);
- mutex_unlock(&ss_list->ss_mutex);
-}
-
-/**
- * Find an entry from the Session list
- * @id: session id to find session node
- * @ss_list: session list contain the session node
- */
-struct hdcp_session_node *hdcp_session_list_find(uint32_t id)
-{
- struct hdcp_session_node *pos;
- struct hdcp_session_node *ss_head;
- struct hdcp_session_list *ss_list = &g_hdcp_session_list;
-
- mutex_lock(&ss_list->ss_mutex);
- ss_head = &ss_list->hdcp_session_head;
- for (pos = ss_head->next; pos != ss_head && pos != NULL; pos = pos->next) {
- if (pos->ss_data->id == id) {
- mutex_unlock(&ss_list->ss_mutex);
- return pos;
- }
- }
- mutex_unlock(&ss_list->ss_mutex);
-
- return NULL;
-}
-
-/**
- * close all links in the session and remove all session nodes
- * @ss_list: session list to remove all
- */
-void hdcp_session_list_destroy(void)
-{
- struct hdcp_session_node *pos;
- struct hdcp_session_node *ss_head;
- struct hdcp_session_list *ss_list = &g_hdcp_session_list;
-
- mutex_lock(&ss_list->ss_mutex);
- ss_head = &ss_list->hdcp_session_head;
- for (pos = ss_head->next; pos != ss_head && pos != NULL;) {
- if (pos) {
- /* remove session node from the list*/
- pos->prev->next = pos->next;
- pos->next->prev = pos->prev;
-
- /* remove session data */
- /* TODO : remove all links */
- hdcp_session_data_destroy(&pos->ss_data);
- if (pos)
- kfree(pos);
- pos = ss_head->next;
- }
- }
- ss_head->next = ss_head;
- ss_head->prev = ss_head;
- mutex_unlock(&ss_list->ss_mutex);
-}
-
-/**
- * init a Link list
- * @lk_list: list head to add it after
- */
-void hdcp_link_list_init(struct hdcp_link_list *lk_list)
-{
- struct hdcp_link_node *lk_head;
-
- if (!lk_list)
- return;
-
- /* initialize link list mutex */
- mutex_init(&lk_list->lk_mutex);
-
- mutex_lock(&lk_list->lk_mutex);
- lk_head = &(lk_list->hdcp_link_head);
- lk_head->next = lk_head;
- lk_head->prev = lk_head;
- lk_head->lk_data = NULL;
- mutex_unlock(&lk_list->lk_mutex);
-}
-
-/**
- * add a new entry to the Link list
- * @new_ent: new entry to be added
- * @ss_list: list head to add it after
- *
- * Insert a new entry after the specified head
- */
-void hdcp_link_list_add(struct hdcp_link_node *new_ent, struct hdcp_link_list *lk_list)
-{
- struct hdcp_link_node *lk_head;
-
- if (!new_ent || !lk_list)
- return;
-
- mutex_lock(&lk_list->lk_mutex);
- lk_head = &(lk_list->hdcp_link_head);
- lk_head->next->prev = new_ent;
- new_ent->next = lk_head->next;
- new_ent->prev = lk_head;
- lk_head->next = new_ent;
- mutex_unlock(&lk_list->lk_mutex);
-}
-
-/**
- * delete a entry form the Link list
- * @del_ent: a entry to be deleted
- * @ss_list: session list to remove the session node
- */
-void hdcp_link_list_del(struct hdcp_link_node *del_ent, struct hdcp_link_list *lk_list)
-{
- if (!del_ent || !lk_list)
- return;
-
- mutex_lock(&lk_list->lk_mutex);
- del_ent->prev->next = del_ent->next;
- del_ent->next->prev = del_ent->prev;
- mutex_unlock(&lk_list->lk_mutex);
-}
-
-/**
- * print all entries in the Link list
- * @ss_list: session list to print all nodes
- */
-void hdcp_link_list_print_all(struct hdcp_link_list *lk_list)
-{
- struct hdcp_link_node *pos;
- struct hdcp_link_node *lk_head;
-
- if (!lk_list)
- return;
-
- mutex_lock(&lk_list->lk_mutex);
- lk_head = &lk_list->hdcp_link_head;
- for (pos = lk_head->next; pos != lk_head && pos != NULL; pos = pos->next)
- hdcp_info("Link: %d\n", pos->lk_data->id);
- mutex_unlock(&lk_list->lk_mutex);
-}
-
-/**
- * Find an entry from the Link list
- * @id: Link handle to find link node
- * @lk_list: link list contain the link node
- */
-struct hdcp_link_node *hdcp_link_list_find(uint32_t id, struct hdcp_link_list *lk_list)
-{
- struct hdcp_link_node *pos;
- struct hdcp_link_node *lk_head;
-
- if (!lk_list)
- return NULL;
-
- mutex_lock(&lk_list->lk_mutex);
- lk_head = &lk_list->hdcp_link_head;
- for (pos = lk_head->next; pos != lk_head && pos != NULL; pos = pos->next) {
- if (pos->lk_data->id == id) {
- mutex_unlock(&lk_list->lk_mutex);
- return pos;
- }
- }
- mutex_unlock(&lk_list->lk_mutex);
- return NULL;
-}
-
-/**
- * close all Links and remove all Link nodes
- * @ss_list: session list to remove all
- */
-void hdcp_link_list_destroy(struct hdcp_link_list *lk_list)
-{
- struct hdcp_link_node *pos;
- struct hdcp_link_node *lk_head;
-
- if (!lk_list)
- return;
-
- mutex_lock(&lk_list->lk_mutex);
- lk_head = &(lk_list->hdcp_link_head);
- for (pos = lk_head->next; pos != lk_head && pos != NULL;) {
- /* remove link node from the list*/
- pos->prev->next = pos->next;
- pos->next->prev = pos->prev;
-
- /* remove link data */
- /* TODO : remove all data */
- if (pos)
- kfree(pos);
- pos = lk_head->next;
- }
- lk_head->next = lk_head;
- lk_head->prev = lk_head;
- mutex_unlock(&lk_list->lk_mutex);
-}
diff --git a/exynos-hdcp2-session.h b/exynos-hdcp2-session.h
deleted file mode 100644
index 7620865..0000000
--- a/exynos-hdcp2-session.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * drivers/soc/samsung/exynos-hdcp/exynos-hdcp2-tx-session.h
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef __HDCP_TX_SESSION_H__
-#define __HDCP_TX_SESSION_H__
-
-#include "exynos-hdcp2-protocol-msg.h"
-
-#define WRAP_SKEY_EMPTY 0
-#define WRAP_SKEY_STORED 1
-
-#define HDCP_WITHOUT_STORED_KM 0
-#define HDCP_WITH_STORED_KM 1
-
-#define MAX_IP_LEN 15 /* IP address format is "xxx.xxx.xxx.xxx" */
-#define RECEIVER_ID_BYTE_LEN (40 / 8)
-#define HDCP_PRIVATE_DATA_LEN 16
-#define HDCP_WRAPPED_HMAC_LEN 124
-#define REPEATER 1
-#define NO_RECEIVER 0
-
-
-/**
- * HDCP Link state & data structure
- */
-typedef enum hdcp_tx_hdcp_link_state {
- LINK_ST_INIT = 0,
- LINK_ST_H0_NO_RX_ATTATCHED,
- LINK_ST_H1_TX_LOW_VALUE_CONTENT,
- LINK_ST_A0_DETERMINE_RX_HDCP_CAP,
- LINK_ST_A1_EXCHANGE_MASTER_KEY,
- LINK_ST_A2_LOCALITY_CHECK,
- LINK_ST_A3_EXCHANGE_SESSION_KEY,
- LINK_ST_A4_TEST_REPEATER,
- LINK_ST_A5_AUTHENTICATED,
- LINK_ST_A6_WAIT_RECEIVER_ID_LIST,
- LINK_ST_A7_VERIFY_RECEIVER_ID_LIST,
- LINK_ST_A8_SEND_RECEIVER_ID_LIST_ACK,
- LINK_ST_A9_CONTENT_STREAM_MGT,
- LINK_ST_END
-} hdcp_tx_hdcp_link_state;
-
-struct hdcp_session_node {
- struct hdcp_session_data *ss_data;
- struct hdcp_session_node *next;
- struct hdcp_session_node *prev;
-};
-
-struct hdcp_session_list {
- struct hdcp_session_node hdcp_session_head;
- struct mutex ss_mutex;
-};
-
-struct hdcp_link_data {
- uint32_t id;
- uint32_t state;
- uint8_t stored_km;
- uint32_t errno; /* error code */
- uint32_t lk_type; /* link type */
- struct hdcp_tx_ctx tx_ctx; /* Transmitter context data */
- struct hdcp_rx_ctx rx_ctx; /* Receiver context data */
- struct hdcp_session_node *ss_ptr; /* session pointer link belong */
-};
-
-struct hdcp_link_node {
- struct hdcp_link_data *lk_data;
- struct hdcp_link_node *next;
- struct hdcp_link_node *prev;
-};
-
-struct hdcp_link_list {
- struct hdcp_link_node hdcp_link_head;
- struct mutex lk_mutex;
-};
-
-/**
- * HDCP Session status & data structure
- */
-typedef enum hdcp_tx_ss_state {
- SESS_ST_INIT = 0,
- SESS_ST_LINK_SETUP,
- SESS_ST_END
-} hdcp_tx_ss_state;
-
-struct hdcp_session_data {
- uint32_t id;
- hdcp_tx_ss_state state;
- uint8_t wrap_skey_store;
- uint8_t riv[HDCP_AKE_RTX_BYTE_LEN];
- uint8_t wrap_skey[HDCP_AKE_WKEY_BYTE_LEN];
- struct hdcp_link_list ln;
-};
-
-struct hdcp_session_data *hdcp_session_data_create(void);
-void hdcp_session_data_destroy(struct hdcp_session_data **ss_data);
-struct hdcp_link_data *hdcp_link_data_create(void);
-void hdcp_link_data_destroy(struct hdcp_link_data **lk_data);
-
-/* Session list APIs */
-void hdcp_session_list_init(void);
-void hdcp_session_list_add(struct hdcp_session_node *new_ent);
-void hdcp_session_list_del(struct hdcp_session_node *del_ent);
-void hdcp_session_list_print_all(void);
-void hdcp_session_list_destroy(void);
-struct hdcp_session_node *hdcp_session_list_find(uint32_t id);
-
-/* Link list APIs */
-void hdcp_link_list_init(struct hdcp_link_list *lk_list);
-void hdcp_link_list_add(struct hdcp_link_node *new_ent, struct hdcp_link_list *lk_list);
-void hdcp_link_list_del(struct hdcp_link_node *del_ent, struct hdcp_link_list *lk_list);
-void hdcp_link_list_print_all(struct hdcp_link_list *lk_list);
-void hdcp_link_list_destroy(struct hdcp_link_list *lk_list);
-struct hdcp_link_node *hdcp_link_list_find(uint32_t id, struct hdcp_link_list *lk_list);
-#endif
-
diff --git a/exynos-hdcp2.h b/exynos-hdcp2.h
deleted file mode 100644
index 4ca2e29..0000000
--- a/exynos-hdcp2.h
+++ /dev/null
@@ -1,269 +0,0 @@
-/* driver/soc/samsung/exynos-hdcp/exynos-hdcp2.h
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-#ifndef __EXYNOS_HDCP2_H__
-#define __EXYNOS_HDCP2_H__
-
-#include <linux/device.h>
-#include <linux/fs.h>
-#include <linux/miscdevice.h>
-#include <linux/mutex.h>
-#include <linux/module.h>
-
-#include "exynos-hdcp2-session.h"
-
-#define HDCP_CMD_SESSION_OPEN 0x0001
-#define HDCP_CMD_SESSION_CLOSE 0x0002
-#define HDCP_CMD_LINK_OPEN 0x0003
-#define HDCP_CMD_LINK_CLOSE 0x0004
-#define HDCP_CMD_LINK_AUTH 0x0005
-#define HDCP_CMD_LINK_ENC 0x0006
-
-/* todo: define max message length based on HDCP spec */
-#define HDCP_PROTO_MSG_LEN_MAX 1024
-
-/* HDCP Link types */
-#define HDCP_LINK_TYPE_IIA 0
-#define HDCP_LINK_TYPE_DP 1
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#define TEMP_ERROR -ENOTTY
-
-static char *hdcp_session_st_str[] = {
- "ST_INIT",
- "ST_LINK_SETUP",
- "ST_END",
- NULL
-};
-
-static char *hdcp_link_st_str[] = {
- "ST_INIT",
- "ST_H0_NO_RX_ATTACHED",
- "ST_H1_TX_LOW_VALUE_CONTENT",
- "ST_A0_DETERMINE_RX_HDCP_CAP",
- "ST_A1_EXCHANGE_MASTER_KEY",
- "ST_A2_LOCALITY_CHECK",
- "ST_A3_EXCHANGE_SESSION_KEY",
- "ST_A4_TEST_REPEATER",
- "ST_A5_AUTHENTICATED",
- "ST_A6_WAIT_RECEIVER_ID_LIST",
- "ST_A7_VERIFY_RECEIVER_ID_LIST",
- "ST_A8_SEND_RECEIVER_ID_LIST_ACK",
- "ST_A9_CONTENT_STREAM_MGT",
- "ST_END",
- NULL
-};
-
-#define UPDATE_SESSION_STATE(sess, st) do { \
- printk("[HDCP2]HDCP Session(%d): %s -> %s\n", sess->id, hdcp_session_st_str[sess->state], hdcp_session_st_str[st]); \
- sess->state = st; \
- } while (0)
-
-#define UPDATE_LINK_STATE(link, st) do { \
- printk("[HDCP2]HDCP Link(%d): %s -> %s\n", link->id, hdcp_link_st_str[link->state], hdcp_link_st_str[st]); \
- link->state = st; \
- } while (0)
-
-#define UPDATE_STEP_STATE(step, st) do { \
- printk("[HDCP2]HDCP STEP(%d): %s -> %s\n", st, hdcp_msgid_str[step], hdcp_msgid_str[st]); \
- step = st; \
- } while (0)
-
-enum {
- SEND_MSG = 0,
- RECIEVE_MSG = 1,
- RP_SEND_MSG = 2,
- RP_RECIEVE_MSG = 3,
- ST_SEND_MSG = 4,
- ST_RECIEVE_MSG = 5,
- DONE = 6,
- AUTH_FINISHED = 7,
- RP_FINISHED = 8,
- WAIT_STATE = 100
-};
-
-enum {
- TX_AUTH_SUCCESS = 0,
- TX_AUTH_ERROR_CONNECT_TEE,
- TX_AUTH_ERROR_MAKE_PROTO_MSG,
- TX_AUTH_ERROR_SEND_PROTO_MSG,
- TX_AUTH_ERROR_RECV_PROTO_MSG,
- TX_AUTH_ERROR_TIME_EXCEED,
- TX_AUTH_ERROR_NET_TIMEOUT,
- TX_AUTH_ERROR_NET_CONN_CLOSED,
- TX_AUTH_ERROR_CRYPTO,
- TX_AUTH_ERROR_WRONG_MSG_ID,
- TX_AUTH_ERROR_WRONG_MSG,
- TX_AUTH_ERROR_WRONG_MSG_SIZE,
- TX_AUTH_ERROR_STORE_SKEY,
- TX_AUTH_ERRRO_RESTORE_SKEY,
- TX_AUTH_ERROR_BUFFER_OVERFLLOW,
- TX_AUTH_ERROR_RETRYCOUNT_EXCEED,
- TX_AUTH_ERROR_ABORT,
-};
-
-typedef enum hdcp_result {
- HDCP_SUCCESS = 0,
- HDCP_ERROR_INIT_FAILED,
- HDCP_ERROR_TERMINATE_FAILED,
- HDCP_ERROR_SESSION_OPEN_FAILED,
- HDCP_ERROR_SESSION_CLOSE_FAILED,
- HDCP_ERROR_LINK_OPEN_FAILED,
- HDCP_ERROR_LINK_CLOSE_FAILED,
- HDCP_ERROR_LINK_STREAM_FAILED,
- HDCP_ERROR_AUTHENTICATE_FAILED,
- HDCP_ERROR_COPY_TO_USER_FAILED,
- HDCP_ERROR_COPY_FROM_USER_FAILED,
- HDCP_ERROR_USER_FAILED,
- HDCP_ERROR_RX_NOT_HDCP_CAPABLE,
- HDCP_ERROR_EXCHANGE_KM,
- HDCP_ERROR_LOCALITY_CHECK,
- HDCP_ERROR_EXCHANGE_KS,
- HDCP_ERROR_WAIT_RECEIVER_ID_LIST,
- HDCP_ERROR_VERIFY_RECEIVER_ID_LIST,
- HDCP_ERROR_WAIT_AKE_INIT,
- HDCP_ERROR_MALLOC_FAILED = 0x1000,
- HDCP_ERROR_INVALID_HANDLE,
- HDCP_ERROR_INVALID_INPUT,
- HDCP_ERROR_INVALID_STATE,
- HDCP_ERROR_NET_UNREACHABLE,
- HDCP_ERROR_NET_CLOSED,
- HDCP_ERROR_ENCRYPTION,
- HDCP_ERROR_DECRYPTION,
- HDCP_ERROR_STREAM_MANAGE,
- HDCP_ERROR_WRAP_FAIL,
- HDCP_ERROR_UNWRAP_FAIL,
- HDCP_ERROR_WRONG_SIZE,
- HDCP_ERROR_DO_NOT_SUPPORT_YET,
- HDCP_ERROR_IOCTL_OPEN,
- HDCP_ERROR_END
-} hdcp_result;
-
-enum {
- HDCP_ERROR_INVALID_SESSION_HANDLE = 0x2000,
- HDCP_ERROR_INVALID_SESSION_STATE,
- HDCP_ERROR_INVALID_STREAM_LEN,
-};
-
-struct hdcp_info {
- struct device *dev;
- struct hdcp_session_list ss_list;
-};
-
-struct hdcp_sess_info {
- uint32_t ss_id;
- uint8_t wkey[HDCP_WRAP_MAX_SIZE];
-};
-
-struct hdcp_link_info {
- uint32_t ss_id;
- uint32_t lk_id;
-};
-
-struct hdcp_link_auth {
- uint32_t ss_id;
- uint32_t lk_id;
-};
-
-struct hdcp_link_enc {
- uint32_t ss_id;
- uint32_t lk_id;
-};
-
-struct hdcp_msg_info {
- uint32_t ss_handle;
- uint32_t lk_id;
- uint8_t msg[1024];
- uint32_t msg_len;
- uint32_t next_step;
-};
-
-struct hdcp_stream_info {
- uint32_t ss_id;
- uint32_t lk_id;
- uint32_t num;
- uint8_t type;
- uint16_t stream_pid;
- uint32_t stream_ctr;
- uint8_t msg[1024];
- uint32_t msg_len;
- uint32_t next_step;
-};
-
-struct hdcp_enc_info {
- uint32_t id;
- uint8_t pes_private[16];
- uint32_t priv_len;
- uint8_t str_ctr[4];
- uint8_t input_ctr[8];
- uint64_t input;
- unsigned long input_phys;
- uint32_t input_len;
- uint64_t output;
- unsigned long output_phys;
- uint32_t output_len;
-};
-
-struct hdcp_wrapped_key {
- uint8_t key[16];
- uint8_t enc_key[128];
- uint32_t wrapped;
- uint32_t key_len;
-};
-
-#define HDCP_IOC_SESSION_OPEN _IOWR('S', 1, struct hdcp_sess_info)
-#define HDCP_IOC_SESSION_CLOSE _IOWR('S', 2, struct hdcp_sess_info)
-#define HDCP_IOC_LINK_OPEN _IOWR('S', 3, struct hdcp_link_info)
-#define HDCP_IOC_LINK_CLOSE _IOWR('S', 4, struct hdcp_link_info)
-#define HDCP_IOC_LINK_AUTH _IOWR('S', 5, struct hdcp_msg_info)
-#define HDCP_IOC_LINK_ENC _IOWR('S', 6, struct hdcp_enc_info)
-#define HDCP_IOC_RESERVED_0 _IO('S', 7)
-#define HDCP_IOC_STREAM_MANAGE _IOWR('S', 8, struct hdcp_stream_info)
-#define HDCP_IOC_IIA_TX_SELFTEST _IOWR('S', 90, int)
-#define HDCP_IOC_DPLINK_TX_AUTH _IOWR('S', 100, int)
-#define HDCP_IOC_DPLINK_TX_EMUL _IOWR('S', 110, int)
-#define HDCP_IOC_DPLINK_TX_SELFTEST _IOWR('S', 120, int)
-#define HDCP_IOC_WRAP_KEY _IOWR('S', 200, struct hdcp_wrapped_key)
-#define HDCP_FUNC_TEST_MODE _IOWR('S', 220, int)
-
-typedef struct hdcp_tx_link_handle {
- uint32_t ss_handle;
- uint32_t lk_id;
-} hdcp_tx_link_handle_t;
-
-enum hdcp_result hdcp_session_open(struct hdcp_sess_info *ss_info);
-enum hdcp_result hdcp_session_close(struct hdcp_sess_info *ss_info);
-enum hdcp_result hdcp_link_open(struct hdcp_link_info *link_info, uint32_t lk_type);
-enum hdcp_result hdcp_link_close(struct hdcp_link_info *link_info);
-enum hdcp_result hdcp_link_authenticate(struct hdcp_msg_info *msg_info);
-enum hdcp_result hdcp_link_stream_manage(struct hdcp_stream_info *stream_info);
-enum hdcp_result hdcp_wrap_key(struct hdcp_wrapped_key *key_info);
-enum hdcp_result hdcp_unwrap_key(char *wkey);
-
-/* Displayport */
-enum dp_state {
- DP_DISCONNECT,
- DP_CONNECT,
-};
-
-enum auth_state {
- HDCP_AUTH_PROCESS_IDLE = 0x1,
- HDCP_AUTH_PROCESS_STOP = 0x2,
- HDCP1_AUTH_PROCESS_DONE = 0x3,
- HDCP2_AUTH_PROCESS_DONE = 0x4
-};
-
-#endif
diff --git a/exynos-hdcp2-log.h b/hdcp-log.h
index 5d07c6b..6ee705e 100644
--- a/exynos-hdcp2-log.h
+++ b/hdcp-log.h
@@ -1,19 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
- * drivers/soc/samsung/exynos-hdcp/exynos-hdcp2-log.h
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
+ * Samsung DisplayPort driver.
*
* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
-
#ifndef __EXYNOS_HDCP_LOG_H__
#define __EXYNOS_HDCP_LOG_H__
-#define HDCP_DEBUG
+#undef HDCP_DEBUG
#ifdef HDCP_DEBUG
#define hdcp_debug(fmt, args...) \
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..9420087
--- /dev/null
+++ b/main.c
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Samsung DisplayPort driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/smc.h>
+#include <asm/cacheflush.h>
+#include <linux/soc/samsung/exynos-smc.h>
+
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqreturn.h>
+#include <linux/dma-mapping.h>
+
+#include "exynos-hdcp-interface.h"
+
+#include "auth-control.h"
+#include "hdcp-log.h"
+#include "selftest.h"
+#include "teeif.h"
+
+#define EXYNOS_HDCP_DEV_NAME "hdcp2"
+
+static struct miscdevice hdcp;
+
+static ssize_t hdcp_write(struct file *file, const char __user *buf,
+ size_t len, loff_t *ppos)
+{
+ hdcp_info("Kicking off selftest\n");
+ hdcp_protocol_self_test();
+ return len;
+}
+
+static ssize_t hdcp_read(struct file *filp, char __user *buf,
+ size_t count, loff_t *f_pos)
+{
+ return 0;
+}
+
+static int exynos_hdcp_probe(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static const struct of_device_id exynos_hdcp_of_match_table[] = {
+ { .compatible = "samsung,exynos-hdcp", },
+ { },
+};
+
+static struct platform_driver exynos_hdcp_driver = {
+ .probe = exynos_hdcp_probe,
+ .driver = {
+ .name = "exynos-hdcp",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(exynos_hdcp_of_match_table),
+ }
+};
+
+static int __init hdcp_init(void)
+{
+ int ret;
+
+ hdcp_info("hdcp2 driver init\n");
+
+ ret = misc_register(&hdcp);
+ if (ret) {
+ hdcp_err("hdcp can't register misc on minor=%d\n",
+ MISC_DYNAMIC_MINOR);
+ return ret;
+ }
+
+ hdcp_tee_init();
+ hdcp_auth_worker_init();
+
+ return platform_driver_register(&exynos_hdcp_driver);
+}
+
+static void __exit hdcp_exit(void)
+{
+ misc_deregister(&hdcp);
+ hdcp_tee_close();
+ hdcp_auth_worker_deinit();
+
+ platform_driver_unregister(&exynos_hdcp_driver);
+}
+
+static const struct file_operations hdcp_fops = {
+ .owner = THIS_MODULE,
+ .write = hdcp_write,
+ .read = hdcp_read,
+};
+
+static struct miscdevice hdcp = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = EXYNOS_HDCP_DEV_NAME,
+ .fops = &hdcp_fops,
+};
+
+module_init(hdcp_init);
+module_exit(hdcp_exit);
+
+MODULE_DESCRIPTION("Exynos Secure hdcp driver");
+MODULE_AUTHOR("<hakmin_1.kim@samsung.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/exynos-hdcp2-selftest.c b/selftest.c
index 75b4dee..22bc72f 100644
--- a/exynos-hdcp2-selftest.c
+++ b/selftest.c
@@ -1,31 +1,31 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Platform device driver for HDCP selftest.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
*
- * Copyright (C) 2023 Google LLC
+ * Samsung DisplayPort driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
+#include "selftest.h"
-#include "exynos-hdcp2-selftest.h"
-
+#include <drm/drm_dp_helper.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/soc/samsung/exynos-smc.h>
-#include "exynos-hdcp2.h"
-#include "exynos-hdcp2-dplink.h"
-#include "exynos-hdcp2-dplink-if.h"
-#include "exynos-hdcp2-dplink-inter.h"
-#include "exynos-hdcp2-dplink-reg.h"
-#include "exynos-hdcp2-dplink-protocol-msg.h"
-#include "exynos-hdcp2-teeif.h"
-#include "exynos-hdcp2.h"
-#include "exynos-hdcp2-log.h"
+#include "exynos-hdcp-interface.h"
+#include "teeif.h"
+#include "hdcp-log.h"
#define HDCP_NO_DIGITAL_OUTPUT (0xff)
#define HDCP_V2_3 (5)
+static const uint8_t bcaps[] = { 0x0 };
+static const uint8_t rx_caps[] = { 0x02, 0x00, 0x03 };
static const uint8_t cert_rx[] = {
0x74, 0x5b, 0xb8, 0xbd, 0x04, 0xaf, 0xb5, 0xc5, 0xc6, 0x7b, 0xc5, 0x3a,
0x34, 0x90, 0xa9, 0x54, 0xc0, 0x8f, 0xb7, 0xeb, 0xa1, 0x54, 0xd2, 0x4f,
@@ -93,27 +93,26 @@ static const uint8_t Mprime[] = {
0xdd, 0x26, 0xe9, 0x52, 0x6e, 0x0e, 0x1d, 0x69, 0xc8, 0x84, 0xe4, 0xcc,
0xc8, 0x09, 0xaa, 0xc7, 0x71, 0xe9, 0x97, 0xb5, 0x61, 0x89, 0x09, 0x6e,
0x4d, 0x94, 0x24, 0xc2, 0x1b, 0x64, 0x58, 0xc6 };
-static const uint8_t RxStatus[] = { DP_RXSTATUS_READY |
- DP_RXSTATUS_HPRIME_AVAILABLE |
- DP_RXSTATUS_PAIRING_AVAILABLE };
+static const uint8_t RxStatus[] = { 0x7 };
static int pdp_dpcd_read_for_hdcp22_emu(u32 address, u32 length, u8 *data)
{
int ret = 0;
- const size_t banks[] = {
- DPCD_ADDR_HDCP22_cert_rx, DPCD_ADDR_HDCP22_Hprime,
- DPCD_ADDR_HDCP22_Ekh_km_r, DPCD_ADDR_HDCP22_Lprime,
- DPCD_ADDR_HDCP22_RxInfo, DPCD_ADDR_HDCP22_seq_num_V,
- DPCD_ADDR_HDCP22_Vprime, DPCD_ADDR_HDCP22_Rec_ID_list,
- DPCD_ADDR_HDCP22_Mprime, DPCD_ADDR_HDCP22_RxStatus };
- const size_t banks_size[] = {
- sizeof(cert_rx), sizeof(Hprime), sizeof(Ekh_km_r),
- sizeof(Lprime), sizeof(RxInfo), sizeof(seq_num_V),
- sizeof(Vprime), sizeof(Rec_ID_list), sizeof(Mprime),
- sizeof(RxStatus) };
+ const size_t banks[] = { DP_AUX_HDCP_BCAPS,
+ DP_HDCP_2_2_REG_RX_CAPS_OFFSET, DP_HDCP_2_2_REG_CERT_RX_OFFSET,
+ DP_HDCP_2_2_REG_HPRIME_OFFSET, DP_HDCP_2_2_REG_EKH_KM_RD_OFFSET,
+ DP_HDCP_2_2_REG_LPRIME_OFFSET, DP_HDCP_2_2_REG_RXINFO_OFFSET,
+ DP_HDCP_2_2_REG_SEQ_NUM_V_OFFSET, DP_HDCP_2_2_REG_VPRIME_OFFSET,
+ DP_HDCP_2_2_REG_RECV_ID_LIST_OFFSET, DP_HDCP_2_2_REG_MPRIME_OFFSET,
+ DP_HDCP_2_2_REG_RXSTATUS_OFFSET };
+ const size_t banks_size[] = { sizeof(bcaps),
+ sizeof(rx_caps), sizeof(cert_rx), sizeof(Hprime),
+ sizeof(Ekh_km_r), sizeof(Lprime), sizeof(RxInfo),
+ sizeof(seq_num_V), sizeof(Vprime), sizeof(Rec_ID_list),
+ sizeof(Mprime), sizeof(RxStatus) };
const uint8_t *bank_ptr[] = {
- cert_rx, Hprime, Ekh_km_r, Lprime, RxInfo,
+ bcaps, rx_caps, cert_rx, Hprime, Ekh_km_r, Lprime, RxInfo,
seq_num_V, Vprime, Rec_ID_list, Mprime, RxStatus };
size_t bank_idx;
size_t bank_offset = 0;
@@ -129,7 +128,7 @@ static int pdp_dpcd_read_for_hdcp22_emu(u32 address, u32 length, u8 *data)
hdcp_err("read impossible for DPCD[%x] with length(%u) as it "
"exceeds bank size (%zu) for bank(%zu)\n",
address, length, banks_size[bank_idx], bank_idx);
- return -1;
+ return -EIO;
}
memcpy(data, bank_ptr[bank_idx] + bank_offset, length);
@@ -157,10 +156,9 @@ static const uint8_t m[] = {
0x18, 0xfa, 0xe4, 0x20, 0x6a, 0xfb, 0x51, 0x49, 0x3b, 0xa0, 0xbe, 0xde,
0x0c, 0x46, 0xa9, 0x91 };
static const uint8_t rn[] = { 0x32, 0x75, 0x3e, 0xa8, 0x78, 0xa6, 0x38, 0x1c };
-static const uint8_t Edkey0_ks[] = {
- 0x4c, 0x32, 0x47, 0x12, 0xc4, 0xbe, 0xc6, 0x69 };
-static const uint8_t Edkey1_ks[] = {
- 0x0a, 0xc2, 0x19, 0x64, 0xde, 0x91, 0xf1, 0x83 };
+static const uint8_t Edkey_ks[] = {
+ 0x4c, 0x32, 0x47, 0x12, 0xc4, 0xbe, 0xc6, 0x69, 0x0a, 0xc2, 0x19, 0x64,
+ 0xde, 0x91, 0xf1, 0x83 };
static const uint8_t riv[] = { 0x40, 0x2b, 0x6b, 0x43, 0xc5, 0xe8, 0x86, 0xd8 };
static const uint8_t V[] = { 0x63, 0x6d, 0xc5, 0x08, 0x4d, 0x6c, 0xb1, 0x0e,
0x93, 0xa5, 0x28, 0x67, 0x0f, 0x34, 0x1f, 0x88 };
@@ -172,21 +170,20 @@ static int pdp_dpcd_write_for_hdcp22_emu(u32 address, u32 length, u8 *data)
{
size_t i;
const size_t banks[] = {
- DPCD_ADDR_HDCP22_Rtx, DPCD_ADDR_HDCP22_TxCaps,
- DPCD_ADDR_HDCP22_Ekpub_km, DPCD_ADDR_HDCP22_Ekh_km_w,
- DPCD_ADDR_HDCP22_m, DPCD_ADDR_HDCP22_rn,
- DPCD_ADDR_HDCP22_Edkey0_ks, DPCD_ADDR_HDCP22_Edkey1_ks,
- DPCD_ADDR_HDCP22_riv, DPCD_ADDR_HDCP22_V,
- DPCD_ADDR_HDCP22_seq_num_M, DPCD_ADDR_HDCP22_k,
- DPCD_ADDR_HDCP22_stream_IDtype, DPCD_ADDR_HDCP22_Type };
+ DP_HDCP_2_2_REG_RTX_OFFSET, DP_HDCP_2_2_REG_TXCAPS_OFFSET,
+ DP_HDCP_2_2_REG_EKPUB_KM_OFFSET, DP_HDCP_2_2_REG_EKH_KM_WR_OFFSET,
+ DP_HDCP_2_2_REG_M_OFFSET, DP_HDCP_2_2_REG_RN_OFFSET,
+ DP_HDCP_2_2_REG_EDKEY_KS_OFFSET, DP_HDCP_2_2_REG_RIV_OFFSET,
+ DP_HDCP_2_2_REG_V_OFFSET, DP_HDCP_2_2_REG_SEQ_NUM_M_OFFSET,
+ DP_HDCP_2_2_REG_K_OFFSET, DP_HDCP_2_2_REG_STREAM_ID_TYPE_OFFSET,
+ DP_HDCP_2_2_REG_STREAM_TYPE_OFFSET };
const size_t banks_size[] = {
sizeof(Rtx), sizeof(TxCaps), sizeof(Ekpub_km), sizeof(Ekh_km_w),
- sizeof(m), sizeof(rn), sizeof(Edkey0_ks), sizeof(Edkey1_ks),
- sizeof(riv), sizeof(V), sizeof(seq_num_M), sizeof(k),
- sizeof(stream_IDtype), 0 };
+ sizeof(m), sizeof(rn), sizeof(Edkey_ks), sizeof(riv), sizeof(V),
+ sizeof(seq_num_M), sizeof(k), sizeof(stream_IDtype), 0 };
const uint8_t *bank_ptr[] = {
- Rtx, TxCaps, Ekpub_km, Ekh_km_w, m, rn, Edkey0_ks,
- Edkey1_ks, riv, V, seq_num_M, k, stream_IDtype, NULL };
+ Rtx, TxCaps, Ekpub_km, Ekh_km_w, m, rn, Edkey_ks, riv, V,
+ seq_num_M, k, stream_IDtype, NULL };
size_t bank_idx;
size_t bank_offset = 0;
@@ -201,7 +198,7 @@ static int pdp_dpcd_write_for_hdcp22_emu(u32 address, u32 length, u8 *data)
hdcp_err("write impossible for DPCD[%x] with length(%u) as it "
"exceeds bank size (%zu) for bank(%zu)\n",
address, length, banks_size[bank_idx], bank_idx);
- return -1;
+ return -EIO;
}
if (memcmp(data, bank_ptr[bank_idx] + bank_offset, length) != 0) {
@@ -211,7 +208,7 @@ static int pdp_dpcd_write_for_hdcp22_emu(u32 address, u32 length, u8 *data)
hdcp_err("%02x %02x\n", *(data + i),
*(bank_ptr[bank_idx] + bank_offset + i));
}
- return -1;
+ return -EIO;
}
return 0;
@@ -228,12 +225,6 @@ static int dp_hdcp_protocol_self_test_internal(void) {
hdcp_dplink_connect_state(DP_CONNECT);
- rc = hdcp_tee_send_cmd(HDCP_CMD_AUTH_MANUAL_START);
- if (rc) {
- hdcp_err("starting authentication failed: %d", rc);
- return rc;
- }
-
version = -1;
for (i = 0; i < 50; ++i) {
rc = hdcp_tee_check_protection(&version);
@@ -249,10 +240,10 @@ static int dp_hdcp_protocol_self_test_internal(void) {
}
hdcp_err("FAIL selftest: HDCP_VERSION(%d)\n", version);
- return -1;
+ return -EIO;
}
-int dp_hdcp_protocol_self_test(void) {
+int hdcp_protocol_self_test(void) {
int rc;
rc = exynos_smc(SMC_HDCP_NOTIFY_INTR_NUM, 1, 0, 0);
@@ -271,7 +262,7 @@ int dp_hdcp_protocol_self_test(void) {
return rc;
}
rc = dp_hdcp_protocol_self_test_internal();
- hdcp_tee_disable_enc();
+ hdcp_dplink_connect_state(DP_DISCONNECT);
hdcp_tee_set_test_mode(false);
return rc;
diff --git a/selftest.h b/selftest.h
new file mode 100644
index 0000000..1e2349b
--- /dev/null
+++ b/selftest.h
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ *
+ * Samsung DisplayPort driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __EXYNOS_HDCP2_DPLINK_SELFTEST_H__
+#define __EXYNOS_HDCP2_DPLINK_SELFTEST_H__
+
+int hdcp_protocol_self_test(void);
+
+#endif
diff --git a/exynos-hdcp2-teeif.c b/teeif.c
index d846709..4ed2a81 100644
--- a/exynos-hdcp2-teeif.c
+++ b/teeif.c
@@ -1,8 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
- * drivers/soc/samsung/exynos-hdcp/exynos-hdcp2-teeif.c
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
+ * Samsung DisplayPort driver.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -17,9 +17,8 @@
#include <asm/cacheflush.h>
#include <linux/dma-mapping.h>
-#include "exynos-hdcp2-teeif.h"
-#include "exynos-hdcp2.h"
-#include "exynos-hdcp2-log.h"
+#include "teeif.h"
+#include "hdcp-log.h"
#define TZ_CON_TIMEOUT 5000
#define TZ_BUF_TIMEOUT 10000
@@ -115,7 +114,7 @@ int hdcp_tee_open(void)
struct tipc_chan *chan;
if (hdcp_ta_ctx.chan) {
- hdcp_info("HCI is already connected\n");
+ hdcp_debug("HCI is already connected\n");
return 0;
}
@@ -527,11 +526,11 @@ int teei_set_rcvlist_info(uint8_t *rx_info,
ret = hdcp_tee_comm(hci);
if (ret != 0) {
- *valid = 1;
+ *valid = 0;
return ret;
}
memcpy(v, hci->setrcvlist.v, HDCP_RP_HMAC_V_LEN / 2);
- *valid = 0;
+ *valid = 1;
return 0;
}
@@ -584,13 +583,15 @@ int teei_verify_m_prime(uint8_t *m_prime, uint8_t *input, size_t input_len)
return ret;
}
-int teei_ksv_exchange(uint64_t bksv, uint64_t *aksv, uint64_t *an) {
+int teei_ksv_exchange(uint64_t bksv, uint32_t is_repeater, uint64_t *aksv,
+ uint64_t *an) {
int ret = 0;
struct hci_message msg;
struct hci_message *hci = &msg;
hci->cmd_id = HDCP_TEEI_KSV_EXCHANGE;
hci->ksvexchange.bksv = bksv;
+ hci->ksvexchange.is_repeater = is_repeater;
if ((ret = hdcp_tee_comm(hci)) < 0)
return ret;
diff --git a/exynos-hdcp2-teeif.h b/teeif.h
index 228f249..2e04ea3 100644
--- a/exynos-hdcp2-teeif.h
+++ b/teeif.h
@@ -1,7 +1,8 @@
-/* drivers/soc/samsung/exynos-hdcp/exynos-hdcp2-teeif.h
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
+ * Samsung DisplayPort driver.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -10,6 +11,8 @@
#ifndef __EXYNOS_HDCP2_TEEIF_H__
#define __EXYNOS_HDCP2_TEEIF_H__
+#include <linux/types.h>
+
/* SMC list for HDCP functions */
#define SMC_HDCP_INIT ((unsigned int)0x82004010)
#define SMC_HDCP_TERMINATE ((unsigned int)0x82004011)
@@ -227,6 +230,7 @@ typedef struct {
uint64_t bksv;
uint64_t an;
uint64_t aksv;
+ uint32_t is_repeater;
} hci_ksvexchange_t;
typedef struct {
@@ -335,7 +339,8 @@ int teei_gen_stream_manage(uint16_t stream_num,
int teei_verify_m_prime(uint8_t *m_prime, uint8_t *input, size_t input_len);
int teei_verify_r_prime(uint16_t rprime);
-int teei_ksv_exchange(uint64_t bksv, uint64_t *aksv, uint64_t *an);
+int teei_ksv_exchange(uint64_t bksv, uint32_t is_repeater,
+ uint64_t *aksv, uint64_t *an);
int teei_verify_v_prime(uint16_t binfo, uint8_t *ksv, uint32_t ksv_len,
uint8_t *vprime);