summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorShivaprasad Hongal <shongal@codeaurora.org>2016-05-12 18:18:53 -0700
committerKyle Yan <kyan@codeaurora.org>2016-06-23 14:01:18 -0700
commitdca874b47a1e084eade65db5a19e2e72a1b3fa22 (patch)
treedef3aaa6b50fac006a0ec1caff119a4cdefd3654 /drivers
parent5b7681a697921b39b9aa48024494bf6cf80775f7 (diff)
msm: misc: hdcp: support tz hdcp2p2 app interface change
TZ hdcp2p2 app interface has changed to include device, session commands and version control. Update hdcp driver to align. CRs-Fixed: 1027108 Change-Id: I4acdad2f243ea32f6ce10b6c0064ef2a5262fab2 Signed-off-by: Shivaprasad Hongal <shongal@codeaurora.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/misc/hdcp.c948
1 files changed, 755 insertions, 193 deletions
diff --git a/drivers/misc/hdcp.c b/drivers/misc/hdcp.c
index 4a941b9f7600..7d1b9e9121a9 100644
--- a/drivers/misc/hdcp.c
+++ b/drivers/misc/hdcp.c
@@ -92,7 +92,6 @@
*/
#define SLEEP_SET_HW_KEY_MS 300
-
#define QSEECOM_ALIGN_SIZE 0x40
#define QSEECOM_ALIGN_MASK (QSEECOM_ALIGN_SIZE - 1)
#define QSEECOM_ALIGN(x)\
@@ -108,24 +107,42 @@
#define HDCP_TXMTR_SUBSTATE_WAITING_FOR_STREAM_READY_MESSAGE 3
#define HDCP_TXMTR_SUBSTATE_REPEATER_AUTH_COMPLETE 4
+#define HDCP_DEVICE_ID 0x0008000
+#define HDCP_CREATE_DEVICE_ID(x) (HDCP_DEVICE_ID | (x))
+
+#define HDCP_TXMTR_HDMI HDCP_CREATE_DEVICE_ID(1)
#define HDCP_TXMTR_SERVICE_ID 0x0001000
-#define SERVICE_TXMTR_CREATE_CMD(x) (HDCP_TXMTR_SERVICE_ID | x)
-
-#define HDCP_TXMTR_INIT SERVICE_TXMTR_CREATE_CMD(1)
-#define HDCP_TXMTR_DEINIT SERVICE_TXMTR_CREATE_CMD(2)
-#define HDCP_TXMTR_PROCESS_RECEIVED_MESSAGE SERVICE_TXMTR_CREATE_CMD(3)
-#define HDCP_TXMTR_SEND_MESSAGE_TIMEOUT SERVICE_TXMTR_CREATE_CMD(4)
-#define HDCP_TXMTR_SET_HW_KEY SERVICE_TXMTR_CREATE_CMD(5)
-#define HDCP_TXMTR_QUERY_STREAM_TYPE SERVICE_TXMTR_CREATE_CMD(6)
-#define HDCP_TXMTR_GET_KSXORLC128_AND_RIV SERVICE_TXMTR_CREATE_CMD(7)
-#define HDCP_TXMTR_PROVISION_KEY SERVICE_TXMTR_CREATE_CMD(8)
-#define HDCP_TXMTR_GET_TOPOLOGY_INFO SERVICE_TXMTR_CREATE_CMD(9)
-#define HDCP_TXMTR_UPDATE_SRM SERVICE_TXMTR_CREATE_CMD(10)
-/*This API calls the library init function */
-#define HDCP_LIB_INIT SERVICE_TXMTR_CREATE_CMD(11)
-/*This API calls the library deinit function */
-#define HDCP_LIB_DEINIT SERVICE_TXMTR_CREATE_CMD(12)
+#define SERVICE_CREATE_CMD(x) (HDCP_TXMTR_SERVICE_ID | x)
+
+#define HDCP_TXMTR_INIT SERVICE_CREATE_CMD(1)
+#define HDCP_TXMTR_DEINIT SERVICE_CREATE_CMD(2)
+#define HDCP_TXMTR_PROCESS_RECEIVED_MESSAGE SERVICE_CREATE_CMD(3)
+#define HDCP_TXMTR_SEND_MESSAGE_TIMEOUT SERVICE_CREATE_CMD(4)
+#define HDCP_TXMTR_SET_HW_KEY SERVICE_CREATE_CMD(5)
+#define HDCP_TXMTR_QUERY_STREAM_TYPE SERVICE_CREATE_CMD(6)
+#define HDCP_TXMTR_GET_KSXORLC128_AND_RIV SERVICE_CREATE_CMD(7)
+#define HDCP_TXMTR_PROVISION_KEY SERVICE_CREATE_CMD(8)
+#define HDCP_TXMTR_GET_TOPOLOGY_INFO SERVICE_CREATE_CMD(9)
+#define HDCP_TXMTR_UPDATE_SRM SERVICE_CREATE_CMD(10)
+#define HDCP_LIB_INIT SERVICE_CREATE_CMD(11)
+#define HDCP_LIB_DEINIT SERVICE_CREATE_CMD(12)
+#define HDCP_TXMTR_DELETE_PAIRING_INFO SERVICE_CREATE_CMD(13)
+#define HDCP_TXMTR_GET_VERSION SERVICE_CREATE_CMD(14)
+#define HDCP_TXMTR_VERIFY_KEY SERVICE_CREATE_CMD(15)
+#define HDCP_SESSION_INIT SERVICE_CREATE_CMD(16)
+#define HDCP_SESSION_DEINIT SERVICE_CREATE_CMD(17)
+#define HDCP_TXMTR_START_AUTHENTICATE SERVICE_CREATE_CMD(18)
+
+#define HCDP_TXMTR_GET_MAJOR_VERSION(v) (((v) >> 16) & 0xFF)
+#define HCDP_TXMTR_GET_MINOR_VERSION(v) (((v) >> 8) & 0xFF)
+#define HCDP_TXMTR_GET_PATCH_VERSION(v) ((v) & 0xFF)
+
+#define HDCP_CLIENT_MAJOR_VERSION 2
+#define HDCP_CLIENT_MINOR_VERSION 1
+#define HDCP_CLIENT_PATCH_VERSION 0
+#define HDCP_CLIENT_MAKE_VERSION(maj, min, patch) \
+ ((((maj) & 0xFF) << 16) | (((min) & 0xFF) << 8) | ((patch) & 0xFF))
#define HDCP_LIB_EXECUTE(x) {\
if (handle->tethered)\
@@ -137,9 +154,10 @@
enum hdcp_state {
HDCP_STATE_INIT = 0x00,
HDCP_STATE_APP_LOADED = 0x01,
- HDCP_STATE_TXMTR_INIT = 0x02,
- HDCP_STATE_AUTHENTICATED = 0x04,
- HDCP_STATE_ERROR = 0x08
+ HDCP_STATE_SESSION_INIT = 0x02,
+ HDCP_STATE_TXMTR_INIT = 0x04,
+ HDCP_STATE_AUTHENTICATED = 0x08,
+ HDCP_STATE_ERROR = 0x10
};
enum hdcp_element {
@@ -175,40 +193,111 @@ struct __attribute__ ((__packed__)) hdcp1_key_set_rsp {
uint8_t ksv[HDCP1_AKSV_SIZE];
};
-struct __attribute__ ((__packed__)) hdcp_init_req {
+struct __attribute__ ((__packed__)) hdcp_version_req {
+ uint32_t commandid;
+};
+
+struct __attribute__ ((__packed__)) hdcp_version_rsp {
uint32_t commandid;
+ uint32_t commandId;
+ uint32_t appversion;
};
-struct __attribute__ ((__packed__)) hdcp_init_rsp {
+struct __attribute__ ((__packed__)) hdcp_lib_init_req_v1 {
+ uint32_t commandid;
+};
+
+struct __attribute__ ((__packed__)) hdcp_lib_init_rsp_v1 {
uint32_t status;
uint32_t commandid;
uint32_t ctxhandle;
uint32_t timeout;
uint32_t msglen;
- uint8_t message[MAX_TX_MESSAGE_SIZE];
+ uint8_t message[MAX_TX_MESSAGE_SIZE];
};
+struct __attribute__ ((__packed__)) hdcp_lib_init_req {
+ uint32_t commandid;
+ uint32_t clientversion;
+};
-struct __attribute__ ((__packed__)) hdcp_deinit_req {
+struct __attribute__ ((__packed__)) hdcp_lib_init_rsp {
+ uint32_t status;
+ uint32_t commandid;
+ uint32_t appversion;
+};
+
+struct __attribute__ ((__packed__)) hdcp_lib_deinit_req {
+ uint32_t commandid;
+};
+
+struct __attribute__ ((__packed__)) hdcp_lib_deinit_rsp {
+ uint32_t status;
+ uint32_t commandid;
+};
+
+struct __attribute__ ((__packed__)) hdcp_lib_session_init_req {
+ uint32_t commandid;
+ uint32_t deviceid;
+};
+
+struct __attribute__ ((__packed__)) hdcp_lib_session_init_rsp {
+ uint32_t status;
+ uint32_t commandid;
+ uint32_t sessionid;
+};
+
+struct __attribute__ ((__packed__)) hdcp_lib_session_deinit_req {
+ uint32_t commandid;
+ uint32_t sessionid;
+};
+
+struct __attribute__ ((__packed__)) hdcp_lib_session_deinit_rsp {
+ uint32_t status;
+ uint32_t commandid;
+};
+
+struct __attribute__ ((__packed__)) hdcp_tx_init_req_v1 {
+ uint32_t commandid;
+};
+
+struct __attribute__ ((__packed__)) hdcp_tx_init_rsp_v1 {
+ uint32_t status;
uint32_t commandid;
uint32_t ctxhandle;
+ uint32_t timeout;
+ uint32_t msglen;
+ uint8_t message[MAX_TX_MESSAGE_SIZE];
};
+struct __attribute__ ((__packed__)) hdcp_tx_init_req {
+ uint32_t commandid;
+ uint32_t sessionid;
+};
-struct __attribute__ ((__packed__)) hdcp_deinit_rsp {
+struct __attribute__ ((__packed__)) hdcp_tx_init_rsp {
uint32_t status;
uint32_t commandid;
+ uint32_t ctxhandle;
};
+struct __attribute__ ((__packed__)) hdcp_deinit_req {
+ uint32_t commandid;
+ uint32_t ctxhandle;
+};
+
+struct __attribute__ ((__packed__)) hdcp_deinit_rsp {
+ uint32_t status;
+ uint32_t commandid;
+};
struct __attribute__ ((__packed__)) hdcp_rcvd_msg_req {
uint32_t commandid;
uint32_t ctxhandle;
uint32_t msglen;
- uint8_t msg[MAX_RX_MESSAGE_SIZE];
+ uint8_t msg[MAX_RX_MESSAGE_SIZE];
};
-
struct __attribute__ ((__packed__)) hdcp_rcvd_msg_rsp {
uint32_t status;
uint32_t commandid;
@@ -216,34 +305,30 @@ struct __attribute__ ((__packed__)) hdcp_rcvd_msg_rsp {
uint32_t timeout;
uint32_t flag;
uint32_t msglen;
- uint8_t msg[MAX_TX_MESSAGE_SIZE];
+ uint8_t msg[MAX_TX_MESSAGE_SIZE];
};
-
struct __attribute__ ((__packed__)) hdcp_set_hw_key_req {
uint32_t commandid;
uint32_t ctxhandle;
};
-
struct __attribute__ ((__packed__)) hdcp_set_hw_key_rsp {
uint32_t status;
uint32_t commandid;
};
-
struct __attribute__ ((__packed__)) hdcp_send_timeout_req {
uint32_t commandid;
uint32_t ctxhandle;
};
-
struct __attribute__ ((__packed__)) hdcp_send_timeout_rsp {
uint32_t status;
uint32_t commandid;
uint32_t timeout;
uint32_t msglen;
- uint8_t message[MAX_TX_MESSAGE_SIZE];
+ uint8_t message[MAX_TX_MESSAGE_SIZE];
};
struct __attribute__ ((__packed__)) hdcp_query_stream_type_req {
@@ -256,13 +341,13 @@ struct __attribute__ ((__packed__)) hdcp_query_stream_type_rsp {
uint32_t commandid;
uint32_t timeout;
uint32_t msglen;
- uint8_t msg[MAX_TX_MESSAGE_SIZE];
+ uint8_t msg[MAX_TX_MESSAGE_SIZE];
};
struct __attribute__ ((__packed__)) hdcp_set_stream_type_req {
uint32_t commandid;
uint32_t ctxhandle;
- uint8_t streamtype;
+ uint8_t streamtype;
};
struct __attribute__ ((__packed__)) hdcp_set_stream_type_rsp {
@@ -270,10 +355,9 @@ struct __attribute__ ((__packed__)) hdcp_set_stream_type_rsp {
uint32_t commandid;
uint32_t timeout;
uint32_t msglen;
- uint8_t message[MAX_TX_MESSAGE_SIZE];
+ uint8_t message[MAX_TX_MESSAGE_SIZE];
};
-
struct __attribute__ ((__packed__)) hdcp_update_srm_req {
uint32_t commandid;
uint32_t ctxhandle;
@@ -281,26 +365,22 @@ struct __attribute__ ((__packed__)) hdcp_update_srm_req {
uint32_t srmlength;
};
-
struct __attribute__ ((__packed__)) hdcp_update_srm_rsp {
uint32_t status;
uint32_t commandid;
};
-
struct __attribute__ ((__packed__)) hdcp_get_topology_req {
uint32_t commandid;
uint32_t ctxhandle;
};
-
struct __attribute__ ((__packed__)) hdcp_get_topology_rsp {
uint32_t status;
uint32_t commandid;
struct topology_info topologyinfo;
};
-
struct __attribute__ ((__packed__)) rxvr_info_struct {
uint8_t rcvrCert[522];
uint8_t rrx[BITS_64_IN_BYTES];
@@ -308,7 +388,6 @@ struct __attribute__ ((__packed__)) rxvr_info_struct {
bool repeater;
};
-
struct __attribute__ ((__packed__)) repeater_info_struct {
uint8_t RxInfo[RXINFO_SIZE];
uint8_t seq_num_V[SEQ_NUM_V_SIZE];
@@ -327,6 +406,20 @@ struct __attribute__ ((__packed__)) hdcp1_set_enc_rsp {
uint32_t ret;
};
+struct __attribute__ ((__packed__)) hdcp_start_auth_req {
+ uint32_t commandid;
+ uint32_t ctxHandle;
+};
+
+struct __attribute__ ((__packed__)) hdcp_start_auth_rsp {
+ uint32_t status;
+ uint32_t commandid;
+ uint32_t ctxhandle;
+ uint32_t timeout;
+ uint32_t msglen;
+ uint8_t message[MAX_TX_MESSAGE_SIZE];
+};
+
/*
* struct hdcp_lib_handle - handle for hdcp client
* @qseecom_handle - for sending commands to qseecom
@@ -361,6 +454,8 @@ struct hdcp_lib_handle {
char *last_msg_recvd_buf;
uint32_t last_msg_recvd_len;
atomic_t hdcp_off;
+ uint32_t session_id;
+ bool legacy_app;
struct task_struct *thread;
struct completion topo_wait;
@@ -373,6 +468,9 @@ struct hdcp_lib_handle {
struct kthread_work wk_clean;
struct kthread_work wk_topology;
struct kthread_work wk_stream;
+
+ int (*hdcp_app_init)(struct hdcp_lib_handle *handle);
+ int (*hdcp_txmtr_init)(struct hdcp_lib_handle *handle);
};
struct hdcp_lib_message_map {
@@ -386,6 +484,8 @@ static void hdcp_lib_msg_sent(struct hdcp_lib_handle *handle);
static void hdcp_lib_msg_recvd(struct hdcp_lib_handle *handle);
static void hdcp_lib_timeout(struct hdcp_lib_handle *handle);
static void hdcp_lib_stream(struct hdcp_lib_handle *handle);
+static int hdcp_lib_txmtr_init(struct hdcp_lib_handle *handle);
+static int hdcp_lib_txmtr_init_legacy(struct hdcp_lib_handle *handle);
static struct qseecom_handle *hdcp1_handle;
static bool hdcp1_supported = true;
@@ -422,22 +522,24 @@ static const char *hdcp_lib_message_name(int msg_id)
}
static inline void hdcp_lib_wakeup_client(struct hdcp_lib_handle *handle,
- struct hdmi_hdcp_wakeup_data *data)
+ struct hdmi_hdcp_wakeup_data *data)
{
int rc = 0;
if (handle && handle->client_ops && handle->client_ops->wakeup &&
- data && (data->cmd != HDMI_HDCP_WKUP_CMD_INVALID)) {
+ data && (data->cmd != HDMI_HDCP_WKUP_CMD_INVALID)) {
rc = handle->client_ops->wakeup(data);
if (rc)
pr_err("error sending %s to client\n",
- hdmi_hdcp_cmd_to_str(data->cmd));
+ hdmi_hdcp_cmd_to_str(data->cmd));
}
}
static inline void hdcp_lib_send_message(struct hdcp_lib_handle *handle)
{
- struct hdmi_hdcp_wakeup_data cdata = {HDMI_HDCP_WKUP_CMD_SEND_MESSAGE};
+ struct hdmi_hdcp_wakeup_data cdata = {
+ HDMI_HDCP_WKUP_CMD_SEND_MESSAGE
+ };
cdata.context = handle->client_ctx;
cdata.send_msg_buf = handle->listener_buf;
@@ -454,7 +556,7 @@ static int hdcp_lib_enable_encryption(struct hdcp_lib_handle *handle)
struct hdcp_set_hw_key_rsp *rsp_buf;
if (!handle || !handle->qseecom_handle ||
- !handle->qseecom_handle->sbuf) {
+ !handle->qseecom_handle->sbuf) {
pr_err("invalid handle\n");
rc = -EINVAL;
goto error;
@@ -466,23 +568,24 @@ static int hdcp_lib_enable_encryption(struct hdcp_lib_handle *handle)
*/
msleep(SLEEP_SET_HW_KEY_MS);
- req_buf = (struct hdcp_set_hw_key_req *)(
- handle->qseecom_handle->sbuf);
+ req_buf = (struct hdcp_set_hw_key_req *)(handle->qseecom_handle->sbuf);
req_buf->commandid = HDCP_TXMTR_SET_HW_KEY;
req_buf->ctxhandle = handle->tz_ctxhandle;
- rsp_buf = (struct hdcp_set_hw_key_rsp *)(
- handle->qseecom_handle->sbuf + QSEECOM_ALIGN(
- sizeof(struct hdcp_set_hw_key_req)));
+ rsp_buf = (struct hdcp_set_hw_key_rsp *)
+ (handle->qseecom_handle->sbuf +
+ QSEECOM_ALIGN(sizeof(struct hdcp_set_hw_key_req)));
rc = qseecom_send_command(handle->qseecom_handle, req_buf,
- QSEECOM_ALIGN(sizeof(struct hdcp_set_hw_key_req)),
- rsp_buf, QSEECOM_ALIGN(sizeof(
- struct hdcp_set_hw_key_rsp)));
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp_set_hw_key_req)),
+ rsp_buf,
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp_set_hw_key_rsp)));
if ((rc < 0) || (rsp_buf->status < 0)) {
pr_err("qseecom cmd failed with err = %d status = %d\n",
- rc, rsp_buf->status);
+ rc, rsp_buf->status);
rc = -EINVAL;
goto error;
}
@@ -499,11 +602,12 @@ error:
return rc;
}
-static int hdcp_lib_library_load(struct hdcp_lib_handle *handle)
+static int hdcp_lib_get_version(struct hdcp_lib_handle *handle)
{
int rc = 0;
- struct hdcp_init_req *req_buf;
- struct hdcp_init_rsp *rsp_buf;
+ struct hdcp_version_req *req_buf;
+ struct hdcp_version_rsp *rsp_buf;
+ uint32_t app_major_version = 0;
if (!handle) {
pr_err("invalid input\n");
@@ -515,12 +619,173 @@ static int hdcp_lib_library_load(struct hdcp_lib_handle *handle)
return rc;
}
+ /* get the TZ hdcp2p2 app version */
+ req_buf = (struct hdcp_version_req *)handle->qseecom_handle->sbuf;
+ req_buf->commandid = HDCP_TXMTR_GET_VERSION;
+
+ rsp_buf = (struct hdcp_version_rsp *)
+ (handle->qseecom_handle->sbuf +
+ QSEECOM_ALIGN(sizeof(struct hdcp_version_req)));
+
+ rc = qseecom_send_command(handle->qseecom_handle,
+ req_buf,
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp_lib_init_req)),
+ rsp_buf,
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp_lib_init_rsp)));
+
+ if (rc < 0) {
+ pr_err("qseecom cmd failed err = %d\n", rc);
+ goto exit;
+ }
+
+ app_major_version = HCDP_TXMTR_GET_MAJOR_VERSION(rsp_buf->appversion);
+
+ pr_debug("hdp2p2 app major version %d, app version %d\n",
+ app_major_version, rsp_buf->appversion);
+
+ if (app_major_version == 1)
+ handle->legacy_app = true;
+
+exit:
+ return rc;
+}
+
+static int hdcp_app_init_legacy(struct hdcp_lib_handle *handle)
+{
+ int rc = 0;
+ struct hdcp_lib_init_req_v1 *req_buf;
+ struct hdcp_lib_init_rsp_v1 *rsp_buf;
+
+ if (!handle) {
+ pr_err("invalid input\n");
+ goto exit;
+ }
+
+ if (!handle->legacy_app) {
+ pr_err("wrong init function\n");
+ goto exit;
+ }
+
+ if (handle->hdcp_state & HDCP_STATE_APP_LOADED) {
+ pr_err("library already loaded\n");
+ goto exit;
+ }
+
+ /* now load the app by sending hdcp_lib_init */
+ req_buf = (struct hdcp_lib_init_req_v1 *)handle->qseecom_handle->sbuf;
+ req_buf->commandid = HDCP_LIB_INIT;
+ rsp_buf = (struct hdcp_lib_init_rsp_v1 *)
+ (handle->qseecom_handle->sbuf +
+ QSEECOM_ALIGN(sizeof(struct hdcp_lib_init_req_v1)));
+
+ rc = qseecom_send_command(handle->qseecom_handle,
+ req_buf,
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp_lib_init_req_v1)),
+ rsp_buf,
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp_lib_init_rsp_v1)));
+
+ if (rc < 0) {
+ pr_err("qseecom cmd failed err = %d\n", rc);
+ goto exit;
+ }
+
+ pr_debug("success\n");
+
+exit:
+ return rc;
+}
+
+static int hdcp_app_init(struct hdcp_lib_handle *handle)
+{
+ int rc = 0;
+ struct hdcp_lib_init_req *req_buf;
+ struct hdcp_lib_init_rsp *rsp_buf;
+ uint32_t app_minor_version = 0;
+
+ if (!handle) {
+ pr_err("invalid input\n");
+ goto exit;
+ }
+
+ if (handle->legacy_app) {
+ pr_err("wrong init function\n");
+ goto exit;
+ }
+
+ if (handle->hdcp_state & HDCP_STATE_APP_LOADED) {
+ pr_err("library already loaded\n");
+ goto exit;
+ }
+
+ /* now load the app by sending hdcp_lib_init */
+ req_buf = (struct hdcp_lib_init_req *)handle->qseecom_handle->sbuf;
+ req_buf->commandid = HDCP_LIB_INIT;
+ req_buf->clientversion =
+ HDCP_CLIENT_MAKE_VERSION(HDCP_CLIENT_MAJOR_VERSION,
+ HDCP_CLIENT_MINOR_VERSION,
+ HDCP_CLIENT_PATCH_VERSION);
+ rsp_buf = (struct hdcp_lib_init_rsp *)
+ (handle->qseecom_handle->sbuf +
+ QSEECOM_ALIGN(sizeof(struct hdcp_lib_init_req)));
+
+ rc = qseecom_send_command(handle->qseecom_handle,
+ req_buf,
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp_lib_init_req)),
+ rsp_buf,
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp_lib_init_rsp)));
+
+ if (rc < 0) {
+ pr_err("qseecom cmd failed err = %d\n", rc);
+ goto exit;
+ }
+
+ app_minor_version = HCDP_TXMTR_GET_MINOR_VERSION(rsp_buf->appversion);
+ if (app_minor_version != HDCP_CLIENT_MINOR_VERSION) {
+ pr_err
+ ("client-app minor version mismatch app(%d), client(%d)\n",
+ app_minor_version, HDCP_CLIENT_MINOR_VERSION);
+ rc = -1;
+ goto exit;
+ }
+ pr_debug("success\n");
+ pr_debug("client version major(%d), minor(%d), patch(%d)\n",
+ HDCP_CLIENT_MAJOR_VERSION, HDCP_CLIENT_MINOR_VERSION,
+ HDCP_CLIENT_PATCH_VERSION);
+ pr_debug("app version major(%d), minor(%d), patch(%d)\n",
+ HCDP_TXMTR_GET_MAJOR_VERSION(rsp_buf->appversion),
+ HCDP_TXMTR_GET_MINOR_VERSION(rsp_buf->appversion),
+ HCDP_TXMTR_GET_PATCH_VERSION(rsp_buf->appversion));
+
+exit:
+ return rc;
+}
+
+static int hdcp_lib_library_load(struct hdcp_lib_handle *handle)
+{
+ int rc = 0;
+
+ if (!handle) {
+ pr_err("invalid input\n");
+ goto exit;
+ }
+
+ if (handle->hdcp_state & HDCP_STATE_APP_LOADED) {
+ pr_err("library already loaded\n");
+ goto exit;
+ }
+
/*
* allocating resource for qseecom handle
* the app is not loaded here
*/
rc = qseecom_start_app(&(handle->qseecom_handle),
- TZAPP_NAME, QSEECOM_SBUFF_SIZE);
+ TZAPP_NAME, QSEECOM_SBUFF_SIZE);
if (rc) {
pr_err("qseecom_start_app failed %d\n", rc);
goto exit;
@@ -528,22 +793,30 @@ static int hdcp_lib_library_load(struct hdcp_lib_handle *handle)
pr_debug("qseecom_start_app success\n");
- /* now load the app by sending hdcp_lib_init */
- req_buf = (struct hdcp_init_req *)handle->qseecom_handle->sbuf;
- req_buf->commandid = HDCP_LIB_INIT;
- rsp_buf = (struct hdcp_init_rsp *)(handle->qseecom_handle->
- sbuf + QSEECOM_ALIGN(sizeof(struct hdcp_init_req)));
+ rc = hdcp_lib_get_version(handle);
+ if (rc) {
+ pr_err("library get version failed\n");
+ goto exit;
+ }
- rc = qseecom_send_command(handle->qseecom_handle,
- req_buf, QSEECOM_ALIGN(sizeof(struct hdcp_init_req)),
- rsp_buf, QSEECOM_ALIGN(sizeof(struct hdcp_init_rsp)));
+ if (handle->legacy_app) {
+ handle->hdcp_app_init = hdcp_app_init_legacy;
+ handle->hdcp_txmtr_init = hdcp_lib_txmtr_init_legacy;
+ } else {
+ handle->hdcp_app_init = hdcp_app_init;
+ handle->hdcp_txmtr_init = hdcp_lib_txmtr_init;
+ }
- if (rc < 0) {
- pr_err("qseecom cmd failed err = %d\n", rc);
+ if (handle->hdcp_app_init == NULL) {
+ pr_err("invalid app init function pointer\n");
goto exit;
}
- pr_debug("success\n");
+ rc = handle->hdcp_app_init(handle);
+ if (rc) {
+ pr_err("app init failed\n");
+ goto exit;
+ }
handle->hdcp_state |= HDCP_STATE_APP_LOADED;
exit:
@@ -553,11 +826,11 @@ exit:
static int hdcp_lib_library_unload(struct hdcp_lib_handle *handle)
{
int rc = 0;
- struct hdcp_deinit_req *req_buf;
- struct hdcp_deinit_rsp *rsp_buf;
+ struct hdcp_lib_deinit_req *req_buf;
+ struct hdcp_lib_deinit_rsp *rsp_buf;
if (!handle || !handle->qseecom_handle ||
- !handle->qseecom_handle->sbuf) {
+ !handle->qseecom_handle->sbuf) {
pr_err("invalid handle\n");
rc = -EINVAL;
goto exit;
@@ -569,15 +842,19 @@ static int hdcp_lib_library_unload(struct hdcp_lib_handle *handle)
}
/* unloading app by sending hdcp_lib_deinit cmd */
- req_buf = (struct hdcp_deinit_req *)handle->
- qseecom_handle->sbuf;
+ req_buf = (struct hdcp_lib_deinit_req *)handle->qseecom_handle->sbuf;
req_buf->commandid = HDCP_LIB_DEINIT;
- rsp_buf = (struct hdcp_deinit_rsp *)(handle->qseecom_handle->
- sbuf + QSEECOM_ALIGN(sizeof(struct hdcp_deinit_req)));
+ rsp_buf = (struct hdcp_lib_deinit_rsp *)
+ (handle->qseecom_handle->sbuf +
+ QSEECOM_ALIGN(sizeof(struct hdcp_lib_deinit_req)));
rc = qseecom_send_command(handle->qseecom_handle,
- req_buf, QSEECOM_ALIGN(sizeof(struct hdcp_deinit_req)),
- rsp_buf, QSEECOM_ALIGN(sizeof(struct hdcp_deinit_rsp)));
+ req_buf,
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp_lib_deinit_req)),
+ rsp_buf,
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp_lib_deinit_rsp)));
if (rc < 0) {
pr_err("qseecom cmd failed err = %d\n", rc);
@@ -597,14 +874,183 @@ exit:
return rc;
}
+static int hdcp_lib_session_init(struct hdcp_lib_handle *handle)
+{
+ int rc = 0;
+ struct hdcp_lib_session_init_req *req_buf;
+ struct hdcp_lib_session_init_rsp *rsp_buf;
+
+ if (!handle || !handle->qseecom_handle ||
+ !handle->qseecom_handle->sbuf) {
+ pr_err("invalid handle\n");
+ rc = -EINVAL;
+ goto exit;
+ }
+
+ if (!(handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
+ pr_err("app not loaded\n");
+ goto exit;
+ }
+
+ if (handle->hdcp_state & HDCP_STATE_SESSION_INIT) {
+ pr_err("session already initialized\n");
+ goto exit;
+ }
+
+ /* send HDCP_Session_Init command to TZ */
+ req_buf =
+ (struct hdcp_lib_session_init_req *)handle->qseecom_handle->sbuf;
+ req_buf->commandid = HDCP_SESSION_INIT;
+ req_buf->deviceid = HDCP_TXMTR_HDMI;
+ rsp_buf = (struct hdcp_lib_session_init_rsp *)
+ (handle->qseecom_handle->sbuf +
+ QSEECOM_ALIGN(sizeof(struct hdcp_lib_session_init_req)));
+
+ rc = qseecom_send_command(handle->qseecom_handle, req_buf,
+ QSEECOM_ALIGN(sizeof
+ (struct
+ hdcp_lib_session_init_req)),
+ rsp_buf,
+ QSEECOM_ALIGN(sizeof
+ (struct
+ hdcp_lib_session_init_rsp)));
+
+ if ((rc < 0) || (rsp_buf->status != HDCP_SUCCESS) ||
+ (rsp_buf->commandid != HDCP_SESSION_INIT)) {
+ pr_err("qseecom cmd failed with err = %d, status = %d\n",
+ rc, rsp_buf->status);
+ rc = -EINVAL;
+ goto exit;
+ }
+
+ pr_debug("session id %d\n", rsp_buf->sessionid);
+
+ handle->session_id = rsp_buf->sessionid;
+ handle->hdcp_state |= HDCP_STATE_SESSION_INIT;
+
+ pr_debug("success\n");
+exit:
+ return rc;
+}
+
+static int hdcp_lib_session_deinit(struct hdcp_lib_handle *handle)
+{
+ int rc = 0;
+ struct hdcp_lib_session_deinit_req *req_buf;
+ struct hdcp_lib_session_deinit_rsp *rsp_buf;
+
+ if (!handle || !handle->qseecom_handle ||
+ !handle->qseecom_handle->sbuf) {
+ pr_err("invalid handle\n");
+ rc = -EINVAL;
+ goto exit;
+ }
+
+ if (!(handle->hdcp_state & HDCP_STATE_APP_LOADED)) {
+ pr_err("app not loaded\n");
+ goto exit;
+ }
+
+ if (!(handle->hdcp_state & HDCP_STATE_SESSION_INIT)) {
+ /* unload library here */
+ pr_err("session not initialized\n");
+ goto exit;
+ }
+
+ /* send command to TZ */
+ req_buf =
+ (struct hdcp_lib_session_deinit_req *)handle->qseecom_handle->sbuf;
+ req_buf->commandid = HDCP_SESSION_DEINIT;
+ req_buf->sessionid = handle->session_id;
+ rsp_buf = (struct hdcp_lib_session_deinit_rsp *)
+ (handle->qseecom_handle->sbuf +
+ QSEECOM_ALIGN(sizeof(struct hdcp_lib_session_deinit_req)));
+
+ rc = qseecom_send_command(handle->qseecom_handle, req_buf,
+ QSEECOM_ALIGN(sizeof
+ (struct
+ hdcp_lib_session_deinit_req)),
+ rsp_buf,
+ QSEECOM_ALIGN(sizeof
+ (struct
+ hdcp_lib_session_deinit_rsp)));
+
+ if ((rc < 0) || (rsp_buf->status < 0) ||
+ (rsp_buf->commandid != HDCP_SESSION_DEINIT)) {
+ pr_err("qseecom cmd failed with err = %d status = %d\n",
+ rc, rsp_buf->status);
+ rc = -EINVAL;
+ goto exit;
+ }
+
+ handle->hdcp_state &= ~HDCP_STATE_SESSION_INIT;
+ pr_debug("success\n");
+exit:
+ return rc;
+}
+
static int hdcp_lib_txmtr_init(struct hdcp_lib_handle *handle)
{
int rc = 0;
- struct hdcp_init_req *req_buf;
- struct hdcp_init_rsp *rsp_buf;
+ struct hdcp_tx_init_req *req_buf;
+ struct hdcp_tx_init_rsp *rsp_buf;
+
+ if (!handle || !handle->qseecom_handle ||
+ !handle->qseecom_handle->sbuf) {
+ pr_err("invalid handle\n");
+ rc = -EINVAL;
+ goto exit;
+ }
+
+ if (!(handle->hdcp_state & HDCP_STATE_SESSION_INIT)) {
+ pr_err("session not initialized\n");
+ goto exit;
+ }
+
+ if (handle->hdcp_state & HDCP_STATE_TXMTR_INIT) {
+ pr_err("txmtr already initialized\n");
+ goto exit;
+ }
+
+ /* send HDCP_Txmtr_Init command to TZ */
+ req_buf = (struct hdcp_tx_init_req *)handle->qseecom_handle->sbuf;
+ req_buf->commandid = HDCP_TXMTR_INIT;
+ req_buf->sessionid = handle->session_id;
+ rsp_buf = (struct hdcp_tx_init_rsp *)
+ (handle->qseecom_handle->sbuf +
+ QSEECOM_ALIGN(sizeof(struct hdcp_tx_init_req)));
+
+ rc = qseecom_send_command(handle->qseecom_handle, req_buf,
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp_tx_init_req)),
+ rsp_buf,
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp_tx_init_rsp)));
+
+ if ((rc < 0) || (rsp_buf->status != HDCP_SUCCESS) ||
+ (rsp_buf->commandid != HDCP_TXMTR_INIT)) {
+ pr_err("qseecom cmd failed with err = %d, status = %d\n",
+ rc, rsp_buf->status);
+ rc = -EINVAL;
+ goto exit;
+ }
+
+ handle->tz_ctxhandle = rsp_buf->ctxhandle;
+ handle->hdcp_state |= HDCP_STATE_TXMTR_INIT;
+
+ pr_debug("success\n");
+exit:
+ return rc;
+}
+
+static int hdcp_lib_txmtr_init_legacy(struct hdcp_lib_handle *handle)
+{
+ int rc = 0;
+ struct hdcp_tx_init_req_v1 *req_buf;
+ struct hdcp_tx_init_rsp_v1 *rsp_buf;
if (!handle || !handle->qseecom_handle ||
- !handle->qseecom_handle->sbuf) {
+ !handle->qseecom_handle->sbuf) {
pr_err("invalid handle\n");
rc = -EINVAL;
goto exit;
@@ -621,33 +1067,36 @@ static int hdcp_lib_txmtr_init(struct hdcp_lib_handle *handle)
}
/* send HDCP_Txmtr_Init command to TZ */
- req_buf = (struct hdcp_init_req *)handle->
- qseecom_handle->sbuf;
+ req_buf = (struct hdcp_tx_init_req_v1 *)handle->qseecom_handle->sbuf;
req_buf->commandid = HDCP_TXMTR_INIT;
- rsp_buf = (struct hdcp_init_rsp *)(handle->qseecom_handle->
- sbuf + QSEECOM_ALIGN(sizeof(struct hdcp_init_req)));
+ rsp_buf = (struct hdcp_tx_init_rsp_v1 *)
+ (handle->qseecom_handle->sbuf +
+ QSEECOM_ALIGN(sizeof(struct hdcp_tx_init_req_v1)));
rc = qseecom_send_command(handle->qseecom_handle, req_buf,
- QSEECOM_ALIGN(sizeof(struct hdcp_init_req)), rsp_buf,
- QSEECOM_ALIGN(sizeof(struct hdcp_init_rsp)));
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp_tx_init_req_v1)),
+ rsp_buf,
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp_tx_init_rsp_v1)));
if ((rc < 0) || (rsp_buf->status != HDCP_SUCCESS) ||
- (rsp_buf->commandid != HDCP_TXMTR_INIT) ||
- (rsp_buf->msglen <= 0) || (rsp_buf->message == NULL)) {
+ (rsp_buf->commandid != HDCP_TXMTR_INIT) ||
+ (rsp_buf->msglen <= 0) || (rsp_buf->message == NULL)) {
pr_err("qseecom cmd failed with err = %d, status = %d\n",
- rc, rsp_buf->status);
+ rc, rsp_buf->status);
rc = -EINVAL;
goto exit;
}
pr_debug("recvd %s from TZ at %dms\n",
- hdcp_lib_message_name((int)rsp_buf->message[0]),
- jiffies_to_msecs(jiffies));
+ hdcp_lib_message_name((int)rsp_buf->message[0]),
+ jiffies_to_msecs(jiffies));
/* send the response to HDMI driver */
memset(handle->listener_buf, 0, MAX_TX_MESSAGE_SIZE);
memcpy(handle->listener_buf, (unsigned char *)rsp_buf->message,
- rsp_buf->msglen);
+ rsp_buf->msglen);
handle->msglen = rsp_buf->msglen;
handle->hdcp_timeout = rsp_buf->timeout;
@@ -666,7 +1115,7 @@ static int hdcp_lib_txmtr_deinit(struct hdcp_lib_handle *handle)
struct hdcp_deinit_rsp *rsp_buf;
if (!handle || !handle->qseecom_handle ||
- !handle->qseecom_handle->sbuf) {
+ !handle->qseecom_handle->sbuf) {
pr_err("invalid handle\n");
rc = -EINVAL;
goto exit;
@@ -684,22 +1133,23 @@ static int hdcp_lib_txmtr_deinit(struct hdcp_lib_handle *handle)
}
/* send command to TZ */
- req_buf = (struct hdcp_deinit_req *)handle->
- qseecom_handle->sbuf;
+ req_buf = (struct hdcp_deinit_req *)handle->qseecom_handle->sbuf;
req_buf->commandid = HDCP_TXMTR_DEINIT;
req_buf->ctxhandle = handle->tz_ctxhandle;
- rsp_buf = (struct hdcp_deinit_rsp *)(handle->
- qseecom_handle->sbuf + QSEECOM_ALIGN(sizeof(
- struct hdcp_deinit_req)));
+ rsp_buf = (struct hdcp_deinit_rsp *)
+ (handle->qseecom_handle->sbuf +
+ QSEECOM_ALIGN(sizeof(struct hdcp_deinit_req)));
rc = qseecom_send_command(handle->qseecom_handle, req_buf,
- QSEECOM_ALIGN(sizeof(struct hdcp_deinit_req)), rsp_buf,
- QSEECOM_ALIGN(sizeof(struct hdcp_deinit_rsp)));
+ QSEECOM_ALIGN(sizeof(struct hdcp_deinit_req)),
+ rsp_buf,
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp_deinit_rsp)));
if ((rc < 0) || (rsp_buf->status < 0) ||
- (rsp_buf->commandid != HDCP_TXMTR_DEINIT)) {
+ (rsp_buf->commandid != HDCP_TXMTR_DEINIT)) {
pr_err("qseecom cmd failed with err = %d status = %d\n",
- rc, rsp_buf->status);
+ rc, rsp_buf->status);
rc = -EINVAL;
goto exit;
}
@@ -710,6 +1160,71 @@ exit:
return rc;
}
+static int hdcp_lib_start_auth(struct hdcp_lib_handle *handle)
+{
+ int rc = 0;
+ struct hdcp_start_auth_req *req_buf;
+ struct hdcp_start_auth_rsp *rsp_buf;
+
+ if (!handle || !handle->qseecom_handle ||
+ !handle->qseecom_handle->sbuf) {
+ pr_err("invalid handle\n");
+ rc = -EINVAL;
+ goto exit;
+ }
+
+ if (!(handle->hdcp_state & HDCP_STATE_SESSION_INIT)) {
+ pr_err("session not initialized\n");
+ goto exit;
+ }
+
+ if (!(handle->hdcp_state & HDCP_STATE_TXMTR_INIT)) {
+ pr_err("txmtr not initialized\n");
+ goto exit;
+ }
+
+ /* send HDCP_Txmtr_Start_Auth command to TZ */
+ req_buf = (struct hdcp_start_auth_req *)handle->qseecom_handle->sbuf;
+ req_buf->commandid = HDCP_TXMTR_START_AUTHENTICATE;
+ req_buf->ctxHandle = handle->tz_ctxhandle;
+ rsp_buf = (struct hdcp_start_auth_rsp *)
+ (handle->qseecom_handle->sbuf +
+ QSEECOM_ALIGN(sizeof(struct hdcp_start_auth_req)));
+
+ rc = qseecom_send_command(handle->qseecom_handle, req_buf,
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp_start_auth_req)),
+ rsp_buf,
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp_start_auth_rsp)));
+
+ if ((rc < 0) || (rsp_buf->status != HDCP_SUCCESS) ||
+ (rsp_buf->commandid != HDCP_TXMTR_START_AUTHENTICATE) ||
+ (rsp_buf->msglen <= 0) || (rsp_buf->message == NULL)) {
+ pr_err("qseecom cmd failed with err = %d, status = %d\n",
+ rc, rsp_buf->status);
+ rc = -EINVAL;
+ goto exit;
+ }
+
+ pr_debug("recvd %s from TZ at %dms\n",
+ hdcp_lib_message_name((int)rsp_buf->message[0]),
+ jiffies_to_msecs(jiffies));
+
+ /* send the response to HDMI driver */
+ memset(handle->listener_buf, 0, MAX_TX_MESSAGE_SIZE);
+ memcpy(handle->listener_buf, (unsigned char *)rsp_buf->message,
+ rsp_buf->msglen);
+ handle->msglen = rsp_buf->msglen;
+ handle->hdcp_timeout = rsp_buf->timeout;
+
+ handle->tz_ctxhandle = rsp_buf->ctxhandle;
+
+ pr_debug("success\n");
+exit:
+ return rc;
+}
+
static void hdcp_lib_stream(struct hdcp_lib_handle *handle)
{
int rc = 0;
@@ -717,7 +1232,7 @@ static void hdcp_lib_stream(struct hdcp_lib_handle *handle)
struct hdcp_query_stream_type_rsp *rsp_buf;
if (!handle || !handle->qseecom_handle ||
- !handle->qseecom_handle->sbuf) {
+ !handle->qseecom_handle->sbuf) {
pr_err("invalid handle\n");
return;
}
@@ -733,33 +1248,38 @@ static void hdcp_lib_stream(struct hdcp_lib_handle *handle)
}
/* send command to TZ */
- req_buf = (struct hdcp_query_stream_type_req *)handle->
- qseecom_handle->sbuf;
+ req_buf =
+ (struct hdcp_query_stream_type_req *)handle->qseecom_handle->sbuf;
req_buf->commandid = HDCP_TXMTR_QUERY_STREAM_TYPE;
req_buf->ctxhandle = handle->tz_ctxhandle;
- rsp_buf = (struct hdcp_query_stream_type_rsp *)(handle->
- qseecom_handle->sbuf + QSEECOM_ALIGN(sizeof(
- struct hdcp_query_stream_type_req)));
+ rsp_buf = (struct hdcp_query_stream_type_rsp *)
+ (handle->qseecom_handle->sbuf +
+ QSEECOM_ALIGN(sizeof(struct hdcp_query_stream_type_req)));
rc = qseecom_send_command(handle->qseecom_handle, req_buf,
- QSEECOM_ALIGN(sizeof(struct hdcp_query_stream_type_req)), rsp_buf,
- QSEECOM_ALIGN(sizeof(struct hdcp_query_stream_type_rsp)));
+ QSEECOM_ALIGN(sizeof
+ (struct
+ hdcp_query_stream_type_req)),
+ rsp_buf,
+ QSEECOM_ALIGN(sizeof
+ (struct
+ hdcp_query_stream_type_rsp)));
if ((rc < 0) || (rsp_buf->status < 0) || (rsp_buf->msglen <= 0) ||
- (rsp_buf->commandid != HDCP_TXMTR_QUERY_STREAM_TYPE) ||
- (rsp_buf->msg == NULL)) {
+ (rsp_buf->commandid != HDCP_TXMTR_QUERY_STREAM_TYPE) ||
+ (rsp_buf->msg == NULL)) {
pr_err("qseecom cmd failed with err=%d status=%d\n",
- rc, rsp_buf->status);
+ rc, rsp_buf->status);
rc = -EINVAL;
goto exit;
}
pr_debug("message received from TZ: %s\n",
- hdcp_lib_message_name((int)rsp_buf->msg[0]));
+ hdcp_lib_message_name((int)rsp_buf->msg[0]));
memset(handle->listener_buf, 0, MAX_TX_MESSAGE_SIZE);
memcpy(handle->listener_buf, (unsigned char *)rsp_buf->msg,
- rsp_buf->msglen);
+ rsp_buf->msglen);
handle->hdcp_timeout = rsp_buf->timeout;
handle->msglen = rsp_buf->msglen;
exit:
@@ -770,7 +1290,8 @@ exit:
static void hdcp_lib_query_stream_work(struct kthread_work *work)
{
struct hdcp_lib_handle *handle = container_of(work,
- struct hdcp_lib_handle, wk_stream);
+ struct hdcp_lib_handle,
+ wk_stream);
hdcp_lib_stream(handle);
}
@@ -885,12 +1406,12 @@ static void hdcp_lib_update_exec_type(void *ctx, bool tethered)
if (handle->tethered == tethered) {
pr_debug("exec mode same as %s\n",
- tethered ? "tethered" : "threaded");
+ tethered ? "tethered" : "threaded");
} else {
handle->tethered = tethered;
pr_debug("exec mode changed to %s\n",
- tethered ? "tethered" : "threaded");
+ tethered ? "tethered" : "threaded");
}
mutex_unlock(&handle->wakeup_mutex);
@@ -914,8 +1435,8 @@ static int hdcp_lib_wakeup(struct hdcp_lib_wakeup_data *data)
handle->timeout_left = data->timeout;
pr_debug("%s, timeout left: %dms, tethered %d\n",
- hdcp_lib_cmd_to_str(handle->wakeup_cmd),
- handle->timeout_left, handle->tethered);
+ hdcp_lib_cmd_to_str(handle->wakeup_cmd),
+ handle->timeout_left, handle->tethered);
rc = hdcp_lib_check_valid_state(handle);
if (rc)
@@ -927,7 +1448,7 @@ static int hdcp_lib_wakeup(struct hdcp_lib_wakeup_data *data)
handle->last_msg_recvd_len = data->recvd_msg_len;
handle->last_msg_recvd_buf = kzalloc(data->recvd_msg_len,
- GFP_KERNEL);
+ GFP_KERNEL);
if (!handle->last_msg_recvd_buf) {
rc = -ENOMEM;
mutex_unlock(&handle->msg_lock);
@@ -935,7 +1456,7 @@ static int hdcp_lib_wakeup(struct hdcp_lib_wakeup_data *data)
}
memcpy(handle->last_msg_recvd_buf, data->recvd_msg_buf,
- data->recvd_msg_len);
+ data->recvd_msg_len);
}
mutex_unlock(&handle->msg_lock);
@@ -950,6 +1471,7 @@ static int hdcp_lib_wakeup(struct hdcp_lib_wakeup_data *data)
handle->last_msg_sent = 0;
handle->hdcp_timeout = 0;
handle->timeout_left = 0;
+ handle->legacy_app = false;
atomic_set(&handle->hdcp_off, 0);
handle->hdcp_state = HDCP_STATE_INIT;
@@ -989,7 +1511,7 @@ exit:
static void hdcp_lib_msg_sent(struct hdcp_lib_handle *handle)
{
- struct hdmi_hdcp_wakeup_data cdata = {HDMI_HDCP_WKUP_CMD_INVALID};
+ struct hdmi_hdcp_wakeup_data cdata = { HDMI_HDCP_WKUP_CMD_INVALID };
if (!handle) {
pr_err("invalid handle\n");
@@ -1003,7 +1525,7 @@ static void hdcp_lib_msg_sent(struct hdcp_lib_handle *handle)
if (handle->repeater_flag) {
if (!atomic_read(&handle->hdcp_off))
queue_kthread_work(&handle->worker,
- &handle->wk_topology);
+ &handle->wk_topology);
}
if (!hdcp_lib_enable_encryption(handle)) {
@@ -1038,7 +1560,8 @@ static void hdcp_lib_msg_sent(struct hdcp_lib_handle *handle)
static void hdcp_lib_msg_sent_work(struct kthread_work *work)
{
struct hdcp_lib_handle *handle = container_of(work,
- struct hdcp_lib_handle, wk_msg_sent);
+ struct hdcp_lib_handle,
+ wk_msg_sent);
if (handle->wakeup_cmd != HDCP_LIB_WKUP_CMD_MSG_SEND_SUCCESS) {
pr_err("invalid wakeup command %d\n", handle->wakeup_cmd);
@@ -1066,10 +1589,27 @@ static void hdcp_lib_init(struct hdcp_lib_handle *handle)
if (rc)
goto exit;
- rc = hdcp_lib_txmtr_init(handle);
+ if (!handle->legacy_app) {
+ rc = hdcp_lib_session_init(handle);
+ if (rc)
+ goto exit;
+ }
+
+ if (handle->hdcp_txmtr_init == NULL) {
+ pr_err("invalid txmtr init function pointer\n");
+ return;
+ }
+
+ rc = handle->hdcp_txmtr_init(handle);
if (rc)
goto exit;
+ if (!handle->legacy_app) {
+ rc = hdcp_lib_start_auth(handle);
+ if (rc)
+ goto exit;
+ }
+
hdcp_lib_send_message(handle);
return;
@@ -1080,7 +1620,8 @@ exit:
static void hdcp_lib_init_work(struct kthread_work *work)
{
struct hdcp_lib_handle *handle = container_of(work,
- struct hdcp_lib_handle, wk_init);
+ struct hdcp_lib_handle,
+ wk_init);
hdcp_lib_init(handle);
}
@@ -1092,7 +1633,7 @@ static void hdcp_lib_timeout(struct hdcp_lib_handle *handle)
struct hdcp_send_timeout_rsp *rsp_buf;
if (!handle || !handle->qseecom_handle ||
- !handle->qseecom_handle->sbuf) {
+ !handle->qseecom_handle->sbuf) {
pr_debug("invalid handle\n");
return;
}
@@ -1103,21 +1644,25 @@ static void hdcp_lib_timeout(struct hdcp_lib_handle *handle)
}
req_buf = (struct hdcp_send_timeout_req *)
- (handle->qseecom_handle->sbuf);
+ (handle->qseecom_handle->sbuf);
req_buf->commandid = HDCP_TXMTR_SEND_MESSAGE_TIMEOUT;
req_buf->ctxhandle = handle->tz_ctxhandle;
- rsp_buf = (struct hdcp_send_timeout_rsp *)(handle->
- qseecom_handle->sbuf + QSEECOM_ALIGN(sizeof(
- struct hdcp_send_timeout_req)));
+ rsp_buf = (struct hdcp_send_timeout_rsp *)
+ (handle->qseecom_handle->sbuf +
+ QSEECOM_ALIGN(sizeof(struct hdcp_send_timeout_req)));
rc = qseecom_send_command(handle->qseecom_handle, req_buf,
- QSEECOM_ALIGN(sizeof(struct hdcp_send_timeout_req)), rsp_buf,
- QSEECOM_ALIGN(sizeof(struct hdcp_send_timeout_rsp)));
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp_send_timeout_req)),
+ rsp_buf,
+ QSEECOM_ALIGN(sizeof
+ (struct
+ hdcp_send_timeout_rsp)));
if ((rc < 0) || (rsp_buf->status != HDCP_SUCCESS)) {
pr_err("qseecom cmd failed for with err = %d status = %d\n",
- rc, rsp_buf->status);
+ rc, rsp_buf->status);
rc = -EINVAL;
goto error;
}
@@ -1133,14 +1678,14 @@ static void hdcp_lib_timeout(struct hdcp_lib_handle *handle)
* send the message again to TZ
*/
if ((rsp_buf->commandid == HDCP_TXMTR_PROCESS_RECEIVED_MESSAGE) &&
- ((int)rsp_buf->message[0] == LC_INIT_MESSAGE_ID) &&
- (rsp_buf->msglen == LC_INIT_MESSAGE_SIZE)) {
+ ((int)rsp_buf->message[0] == LC_INIT_MESSAGE_ID) &&
+ (rsp_buf->msglen == LC_INIT_MESSAGE_SIZE)) {
if (!atomic_read(&handle->hdcp_off)) {
/* keep local copy of TZ response */
memset(handle->listener_buf, 0, MAX_TX_MESSAGE_SIZE);
memcpy(handle->listener_buf,
- (unsigned char *)rsp_buf->message,
- rsp_buf->msglen);
+ (unsigned char *)rsp_buf->message,
+ rsp_buf->msglen);
handle->hdcp_timeout = rsp_buf->timeout;
handle->msglen = rsp_buf->msglen;
@@ -1157,14 +1702,15 @@ error:
static void hdcp_lib_manage_timeout_work(struct kthread_work *work)
{
struct hdcp_lib_handle *handle = container_of(work,
- struct hdcp_lib_handle, wk_timeout);
+ struct hdcp_lib_handle,
+ wk_timeout);
hdcp_lib_timeout(handle);
}
static void hdcp_lib_clean(struct hdcp_lib_handle *handle)
{
- struct hdmi_hdcp_wakeup_data cdata = {HDMI_HDCP_WKUP_CMD_INVALID};
+ struct hdmi_hdcp_wakeup_data cdata = { HDMI_HDCP_WKUP_CMD_INVALID };
if (!handle) {
pr_err("invalid input\n");
@@ -1172,6 +1718,8 @@ static void hdcp_lib_clean(struct hdcp_lib_handle *handle)
};
hdcp_lib_txmtr_deinit(handle);
+ if (!handle->legacy_app)
+ hdcp_lib_session_deinit(handle);
hdcp_lib_library_unload(handle);
cdata.context = handle->client_ctx;
@@ -1183,11 +1731,12 @@ static void hdcp_lib_clean(struct hdcp_lib_handle *handle)
atomic_set(&handle->hdcp_off, 1);
}
-
static void hdcp_lib_cleanup_work(struct kthread_work *work)
{
+
struct hdcp_lib_handle *handle = container_of(work,
- struct hdcp_lib_handle, wk_clean);
+ struct hdcp_lib_handle,
+ wk_clean);
hdcp_lib_clean(handle);
}
@@ -1195,14 +1744,14 @@ static void hdcp_lib_cleanup_work(struct kthread_work *work)
static void hdcp_lib_msg_recvd(struct hdcp_lib_handle *handle)
{
int rc = 0;
- struct hdmi_hdcp_wakeup_data cdata = {HDMI_HDCP_WKUP_CMD_INVALID};
+ struct hdmi_hdcp_wakeup_data cdata = { HDMI_HDCP_WKUP_CMD_INVALID };
struct hdcp_rcvd_msg_req *req_buf;
struct hdcp_rcvd_msg_rsp *rsp_buf;
uint32_t msglen;
char *msg = NULL;
if (!handle || !handle->qseecom_handle ||
- !handle->qseecom_handle->sbuf) {
+ !handle->qseecom_handle->sbuf) {
pr_err("invalid handle\n");
return;
}
@@ -1236,31 +1785,34 @@ static void hdcp_lib_msg_recvd(struct hdcp_lib_handle *handle)
mutex_unlock(&handle->msg_lock);
pr_debug("msg received: %s from sink\n",
- hdcp_lib_message_name((int)msg[0]));
+ hdcp_lib_message_name((int)msg[0]));
/* send the message to QSEECOM */
- req_buf = (struct hdcp_rcvd_msg_req *)(handle->
- qseecom_handle->sbuf);
+ req_buf = (struct hdcp_rcvd_msg_req *)(handle->qseecom_handle->sbuf);
req_buf->commandid = HDCP_TXMTR_PROCESS_RECEIVED_MESSAGE;
memcpy(req_buf->msg, msg, msglen);
req_buf->msglen = msglen;
req_buf->ctxhandle = handle->tz_ctxhandle;
- rsp_buf = (struct hdcp_rcvd_msg_rsp *)(handle->
- qseecom_handle->sbuf + QSEECOM_ALIGN(sizeof(
- struct hdcp_rcvd_msg_req)));
+ rsp_buf =
+ (struct hdcp_rcvd_msg_rsp *)(handle->qseecom_handle->sbuf +
+ QSEECOM_ALIGN(sizeof
+ (struct
+ hdcp_rcvd_msg_req)));
pr_debug("writing %s to TZ at %dms\n",
- hdcp_lib_message_name((int)msg[0]),
- jiffies_to_msecs(jiffies));
+ hdcp_lib_message_name((int)msg[0]), jiffies_to_msecs(jiffies));
rc = qseecom_send_command(handle->qseecom_handle, req_buf,
- QSEECOM_ALIGN(sizeof(struct hdcp_rcvd_msg_req)), rsp_buf,
- QSEECOM_ALIGN(sizeof(struct hdcp_rcvd_msg_rsp)));
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp_rcvd_msg_req)),
+ rsp_buf,
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp_rcvd_msg_rsp)));
/* get next message from sink if we receive H PRIME on no store km */
if ((msg[0] == AKE_SEND_H_PRIME_MESSAGE_ID) &&
- handle->no_stored_km_flag) {
+ handle->no_stored_km_flag) {
handle->hdcp_timeout = rsp_buf->timeout;
cdata.cmd = HDMI_HDCP_WKUP_CMD_RECV_MESSAGE;
@@ -1270,25 +1822,25 @@ static void hdcp_lib_msg_recvd(struct hdcp_lib_handle *handle)
}
if ((msg[0] == REPEATER_AUTH_STREAM_READY_MESSAGE_ID) &&
- (rc == 0) && (rsp_buf->status == 0)) {
+ (rc == 0) && (rsp_buf->status == 0)) {
pr_debug("Got Auth_Stream_Ready, nothing sent to rx\n");
cdata.cmd = HDMI_HDCP_WKUP_CMD_LINK_POLL;
goto exit;
}
- if ((rc < 0) || (rsp_buf->status < 0) || (rsp_buf->msglen <= 0) ||
- (rsp_buf->commandid != HDCP_TXMTR_PROCESS_RECEIVED_MESSAGE) ||
- (rsp_buf->msg == NULL)) {
+ if ((rc < 0) || (rsp_buf->status != 0) || (rsp_buf->msglen <= 0) ||
+ (rsp_buf->commandid != HDCP_TXMTR_PROCESS_RECEIVED_MESSAGE) ||
+ (rsp_buf->msg == NULL)) {
pr_err("qseecom cmd failed with err=%d status=%d\n",
- rc, rsp_buf->status);
+ rc, rsp_buf->status);
rc = -EINVAL;
goto exit;
}
pr_debug("recvd %s from TZ at %dms\n",
- hdcp_lib_message_name((int)rsp_buf->msg[0]),
- jiffies_to_msecs(jiffies));
+ hdcp_lib_message_name((int)rsp_buf->msg[0]),
+ jiffies_to_msecs(jiffies));
/* set the flag if response is AKE_No_Stored_km */
if (((int)rsp_buf->msg[0] == AKE_NO_STORED_KM_MESSAGE_ID)) {
@@ -1300,17 +1852,17 @@ static void hdcp_lib_msg_recvd(struct hdcp_lib_handle *handle)
/* check if it's a repeater */
if ((rsp_buf->msg[0] == SKE_SEND_EKS_MESSAGE_ID) &&
- (rsp_buf->msglen == SKE_SEND_EKS_MESSAGE_SIZE)) {
+ (rsp_buf->msglen == SKE_SEND_EKS_MESSAGE_SIZE)) {
if ((rsp_buf->flag ==
- HDCP_TXMTR_SUBSTATE_WAITING_FOR_RECIEVERID_LIST) &&
- (rsp_buf->timeout > 0))
+ HDCP_TXMTR_SUBSTATE_WAITING_FOR_RECIEVERID_LIST) &&
+ (rsp_buf->timeout > 0))
handle->repeater_flag = true;
- handle->update_stream = true;
+ handle->update_stream = true;
}
memset(handle->listener_buf, 0, MAX_TX_MESSAGE_SIZE);
memcpy(handle->listener_buf, (unsigned char *)rsp_buf->msg,
- rsp_buf->msglen);
+ rsp_buf->msglen);
handle->hdcp_timeout = rsp_buf->timeout;
handle->msglen = rsp_buf->msglen;
@@ -1333,7 +1885,8 @@ exit:
static void hdcp_lib_msg_recvd_work(struct kthread_work *work)
{
struct hdcp_lib_handle *handle = container_of(work,
- struct hdcp_lib_handle, wk_msg_recvd);
+ struct hdcp_lib_handle,
+ wk_msg_recvd);
hdcp_lib_msg_recvd(handle);
}
@@ -1342,7 +1895,8 @@ static void hdcp_lib_topology_work(struct kthread_work *work)
{
u32 timeout;
struct hdcp_lib_handle *handle = container_of(work,
- struct hdcp_lib_handle, wk_topology);
+ struct hdcp_lib_handle,
+ wk_topology);
if (!handle) {
pr_err("invalid input\n");
@@ -1366,7 +1920,7 @@ bool hdcp1_check_if_supported_load_app(void)
/* start hdcp1 app */
if (hdcp1_supported && !hdcp1_handle) {
rc = qseecom_start_app(&hdcp1_handle, HDCP1_APP_NAME,
- QSEECOM_SBUFF_SIZE);
+ QSEECOM_SBUFF_SIZE);
if (rc) {
pr_err("qseecom_start_app failed %d\n", rc);
hdcp1_supported = false;
@@ -1374,7 +1928,7 @@ bool hdcp1_check_if_supported_load_app(void)
}
pr_debug("hdcp1 app %s loaded\n",
- hdcp1_supported ? "successfully" : "not");
+ hdcp1_supported ? "successfully" : "not");
return hdcp1_supported;
}
@@ -1396,10 +1950,13 @@ int hdcp1_set_keys(uint32_t *aksv_msb, uint32_t *aksv_lsb)
key_set_req = (struct hdcp1_key_set_req *)hdcp1_handle->sbuf;
key_set_req->commandid = HDCP1_SET_KEY_MESSAGE_ID;
key_set_rsp = (struct hdcp1_key_set_rsp *)(hdcp1_handle->sbuf +
- QSEECOM_ALIGN(sizeof(struct hdcp1_key_set_req)));
- rc = qseecom_send_command(hdcp1_handle,
- key_set_req, QSEECOM_ALIGN(sizeof(struct hdcp1_key_set_req)),
- key_set_rsp, QSEECOM_ALIGN(sizeof(struct hdcp1_key_set_rsp)));
+ QSEECOM_ALIGN(sizeof(struct hdcp1_key_set_req)));
+ rc = qseecom_send_command(hdcp1_handle, key_set_req,
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp1_key_set_req)),
+ key_set_rsp,
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp1_key_set_rsp)));
if (rc < 0) {
pr_err("qseecom cmd failed err=%d\n", rc);
@@ -1408,8 +1965,7 @@ int hdcp1_set_keys(uint32_t *aksv_msb, uint32_t *aksv_lsb)
rc = key_set_rsp->ret;
if (rc) {
- pr_err("set key cmd failed, rsp=%d\n",
- key_set_rsp->ret);
+ pr_err("set key cmd failed, rsp=%d\n", key_set_rsp->ret);
return -ENOKEY;
}
@@ -1441,9 +1997,12 @@ int hdcp1_set_enc(bool enable)
set_enc_req->enable = enable;
set_enc_rsp = (struct hdcp1_set_enc_rsp *)(hdcp1_handle->sbuf +
QSEECOM_ALIGN(sizeof(struct hdcp1_set_enc_req)));
- rc = qseecom_send_command(hdcp1_handle,
- set_enc_req, QSEECOM_ALIGN(sizeof(struct hdcp1_set_enc_req)),
- set_enc_rsp, QSEECOM_ALIGN(sizeof(struct hdcp1_set_enc_rsp)));
+ rc = qseecom_send_command(hdcp1_handle, set_enc_req,
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp1_set_enc_req)),
+ set_enc_rsp,
+ QSEECOM_ALIGN(sizeof
+ (struct hdcp1_set_enc_rsp)));
if (rc < 0) {
pr_err("qseecom cmd failed err=%d\n", rc);
@@ -1452,8 +2011,7 @@ int hdcp1_set_enc(bool enable)
rc = set_enc_rsp->ret;
if (rc) {
- pr_err("enc cmd failed, rsp=%d\n",
- set_enc_rsp->ret);
+ pr_err("enc cmd failed, rsp=%d\n", set_enc_rsp->ret);
return -EINVAL;
}
@@ -1500,6 +2058,8 @@ int hdcp_library_register(struct hdcp_register_data *data)
handle->client_ctx = data->client_ctx;
handle->client_ops = data->client_ops;
handle->tethered = data->tethered;
+ handle->hdcp_app_init = NULL;
+ handle->hdcp_txmtr_init = NULL;
pr_debug("tethered %d\n", handle->tethered);
@@ -1510,13 +2070,13 @@ int hdcp_library_register(struct hdcp_register_data *data)
init_kthread_worker(&handle->worker);
- init_kthread_work(&handle->wk_init, hdcp_lib_init_work);
- init_kthread_work(&handle->wk_msg_sent, hdcp_lib_msg_sent_work);
+ init_kthread_work(&handle->wk_init, hdcp_lib_init_work);
+ init_kthread_work(&handle->wk_msg_sent, hdcp_lib_msg_sent_work);
init_kthread_work(&handle->wk_msg_recvd, hdcp_lib_msg_recvd_work);
- init_kthread_work(&handle->wk_timeout, hdcp_lib_manage_timeout_work);
- init_kthread_work(&handle->wk_clean, hdcp_lib_cleanup_work);
- init_kthread_work(&handle->wk_topology, hdcp_lib_topology_work);
- init_kthread_work(&handle->wk_stream, hdcp_lib_query_stream_work);
+ init_kthread_work(&handle->wk_timeout, hdcp_lib_manage_timeout_work);
+ init_kthread_work(&handle->wk_clean, hdcp_lib_cleanup_work);
+ init_kthread_work(&handle->wk_topology, hdcp_lib_topology_work);
+ init_kthread_work(&handle->wk_stream, hdcp_lib_query_stream_work);
init_completion(&handle->topo_wait);
@@ -1529,7 +2089,7 @@ int hdcp_library_register(struct hdcp_register_data *data)
*data->hdcp_ctx = handle;
handle->thread = kthread_run(kthread_worker_fn,
- &handle->worker, "hdcp_tz_lib");
+ &handle->worker, "hdcp_tz_lib");
if (IS_ERR(handle->thread)) {
pr_err("unable to start lib thread\n");
@@ -1547,6 +2107,7 @@ error:
unlock:
return rc;
}
+EXPORT_SYMBOL(hdcp_library_register);
void hdcp_library_deregister(void *phdcpcontext)
{
@@ -1565,3 +2126,4 @@ void hdcp_library_deregister(void *phdcpcontext)
kzfree(handle->listener_buf);
kzfree(handle);
}
+EXPORT_SYMBOL(hdcp_library_deregister);