summaryrefslogtreecommitdiff
path: root/drivers/misc
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-08-26 14:48:41 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-08-26 14:48:41 -0700
commit917e5e4c37e43e7e7441b7a5bdbc628798516cdf (patch)
tree23959d2ca9df024c1323848e65d76982d7f6f5cf /drivers/misc
parent6ca1ce42e81c9827756d66f55f0c11867d67fbf2 (diff)
parentf1b139c49ec2a726378003364a5fadb6ad973fed (diff)
Merge "msm: misc: hdcp: add support for multi-part hdcp2p2 messages"
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/hdcp.c124
1 files changed, 123 insertions, 1 deletions
diff --git a/drivers/misc/hdcp.c b/drivers/misc/hdcp.c
index 0c6f1de2465b..76add503b6b8 100644
--- a/drivers/misc/hdcp.c
+++ b/drivers/misc/hdcp.c
@@ -51,6 +51,8 @@
(MESSAGE_ID_SIZE+BITS_128_IN_BYTES+BITS_64_IN_BYTES)
/* all message IDs */
+#define INVALID_MESSAGE_ID 0
+#define AKE_INIT_MESSAGE_ID 2
#define AKE_SEND_CERT_MESSAGE_ID 3
#define AKE_NO_STORED_KM_MESSAGE_ID 4
#define AKE_STORED_KM_MESSAGE_ID 5
@@ -63,6 +65,8 @@
#define REPEATER_AUTH_SEND_ACK_MESSAGE_ID 15
#define REPEATER_AUTH_STREAM_MANAGE_MESSAGE_ID 16
#define REPEATER_AUTH_STREAM_READY_MESSAGE_ID 17
+#define HDCP2P2_MAX_MESSAGES 18
+
#define HDCP1_SET_KEY_MESSAGE_ID 202
#define HDCP1_SET_ENC_MESSAGE_ID 205
@@ -144,6 +148,9 @@
#define HDCP_CLIENT_MAKE_VERSION(maj, min, patch) \
((((maj) & 0xFF) << 16) | (((min) & 0xFF) << 8) | ((patch) & 0xFF))
+#define REAUTH_REQ BIT(3)
+#define LINK_INTEGRITY_FAILURE BIT(4)
+
#define HDCP_LIB_EXECUTE(x) {\
if (handle->tethered)\
hdcp_lib_##x(handle);\
@@ -151,6 +158,48 @@
queue_kthread_work(&handle->worker, &handle->wk_##x);\
}
+static const struct hdcp_msg_data hdcp_msg_lookup[HDCP2P2_MAX_MESSAGES] = {
+ [AKE_INIT_MESSAGE_ID] = { 2,
+ { {0x69000, 8}, {0x69008, 3} },
+ 0 },
+ [AKE_SEND_CERT_MESSAGE_ID] = { 3,
+ { {0x6900B, 522}, {0x69215, 8}, {0x6921D, 3} },
+ 0 },
+ [AKE_NO_STORED_KM_MESSAGE_ID] = { 1,
+ { {0x69220, 128} },
+ 0 },
+ [AKE_STORED_KM_MESSAGE_ID] = { 2,
+ { {0x692A0, 16}, {0x692B0, 16} },
+ 0 },
+ [AKE_SEND_H_PRIME_MESSAGE_ID] = { 1,
+ { {0x692C0, 32} },
+ (1 << 1) },
+ [AKE_SEND_PAIRING_INFO_MESSAGE_ID] = { 1,
+ { {0x692E0, 16} },
+ (1 << 2) },
+ [LC_INIT_MESSAGE_ID] = { 1,
+ { {0x692F0, 8} },
+ 0 },
+ [LC_SEND_L_PRIME_MESSAGE_ID] = { 1,
+ { {0x692F8, 32} },
+ 0 },
+ [SKE_SEND_EKS_MESSAGE_ID] = { 2,
+ { {0x69318, 16}, {0x69328, 8} },
+ 0 },
+ [REPEATER_AUTH_SEND_RECEIVERID_LIST_MESSAGE_ID] = { 4,
+ { {0x69330, 2}, {0x69332, 3}, {0x69335, 16}, {0x69345, 155} },
+ (1 << 0) },
+ [REPEATER_AUTH_SEND_ACK_MESSAGE_ID] = { 1,
+ { {0x693E0, 16} },
+ 0 },
+ [REPEATER_AUTH_STREAM_MANAGE_MESSAGE_ID] = { 3,
+ { {0x693F0, 3}, {0x693F3, 2}, {0x693F5, 126} },
+ 0 },
+ [REPEATER_AUTH_STREAM_READY_MESSAGE_ID] = { 1,
+ { {0x69473, 32} },
+ 0 }
+};
+
enum hdcp_state {
HDCP_STATE_INIT = 0x00,
HDCP_STATE_APP_LOADED = 0x01,
@@ -451,6 +500,7 @@ struct hdcp_lib_handle {
bool tethered;
struct qseecom_handle *qseecom_handle;
int last_msg_sent;
+ int last_msg;
char *last_msg_recvd_buf;
uint32_t last_msg_recvd_len;
atomic_t hdcp_off;
@@ -522,6 +572,50 @@ static const char *hdcp_lib_message_name(int msg_id)
return "UNKNOWN";
}
+static int hdcp_lib_get_next_message(struct hdcp_lib_handle *handle,
+ struct hdmi_hdcp_wakeup_data *data)
+{
+ switch (handle->last_msg) {
+ case INVALID_MESSAGE_ID:
+ return AKE_INIT_MESSAGE_ID;
+ case AKE_INIT_MESSAGE_ID:
+ return AKE_SEND_CERT_MESSAGE_ID;
+ case AKE_SEND_CERT_MESSAGE_ID:
+ if (handle->no_stored_km_flag)
+ return AKE_NO_STORED_KM_MESSAGE_ID;
+ else
+ return AKE_STORED_KM_MESSAGE_ID;
+ case AKE_STORED_KM_MESSAGE_ID:
+ case AKE_NO_STORED_KM_MESSAGE_ID:
+ return AKE_SEND_H_PRIME_MESSAGE_ID;
+ case AKE_SEND_H_PRIME_MESSAGE_ID:
+ if (handle->no_stored_km_flag)
+ return AKE_SEND_PAIRING_INFO_MESSAGE_ID;
+ else
+ return LC_INIT_MESSAGE_ID;
+ case AKE_SEND_PAIRING_INFO_MESSAGE_ID:
+ return LC_INIT_MESSAGE_ID;
+ case LC_INIT_MESSAGE_ID:
+ return LC_SEND_L_PRIME_MESSAGE_ID;
+ case LC_SEND_L_PRIME_MESSAGE_ID:
+ return SKE_SEND_EKS_MESSAGE_ID;
+ case SKE_SEND_EKS_MESSAGE_ID:
+ case REPEATER_AUTH_STREAM_READY_MESSAGE_ID:
+ case REPEATER_AUTH_SEND_ACK_MESSAGE_ID:
+ if (data->cmd == HDMI_HDCP_WKUP_CMD_SEND_MESSAGE)
+ return REPEATER_AUTH_STREAM_MANAGE_MESSAGE_ID;
+ else
+ return REPEATER_AUTH_SEND_RECEIVERID_LIST_MESSAGE_ID;
+ case REPEATER_AUTH_SEND_RECEIVERID_LIST_MESSAGE_ID:
+ return REPEATER_AUTH_SEND_ACK_MESSAGE_ID;
+ case REPEATER_AUTH_STREAM_MANAGE_MESSAGE_ID:
+ return REPEATER_AUTH_STREAM_READY_MESSAGE_ID;
+ default:
+ pr_err("Uknown message ID (%d)", handle->last_msg);
+ return -EINVAL;
+ }
+}
+
static inline void hdcp_lib_wakeup_client(struct hdcp_lib_handle *handle,
struct hdmi_hdcp_wakeup_data *data)
{
@@ -529,6 +623,20 @@ static inline void hdcp_lib_wakeup_client(struct hdcp_lib_handle *handle,
if (handle && handle->client_ops && handle->client_ops->wakeup &&
data && (data->cmd != HDMI_HDCP_WKUP_CMD_INVALID)) {
+ data->abort_mask = REAUTH_REQ | LINK_INTEGRITY_FAILURE;
+
+ if (data->cmd == HDMI_HDCP_WKUP_CMD_SEND_MESSAGE ||
+ data->cmd == HDMI_HDCP_WKUP_CMD_RECV_MESSAGE ||
+ data->cmd == HDMI_HDCP_WKUP_CMD_LINK_POLL) {
+ handle->last_msg =
+ hdcp_lib_get_next_message(handle, data);
+
+ if (handle->last_msg > INVALID_MESSAGE_ID &&
+ handle->last_msg < HDCP2P2_MAX_MESSAGES)
+ data->message_data =
+ &hdcp_msg_lookup[handle->last_msg];
+ }
+
rc = handle->client_ops->wakeup(data);
if (rc)
pr_err("error sending %s to client\n",
@@ -1470,6 +1578,7 @@ static int hdcp_lib_wakeup(struct hdcp_lib_wakeup_data *data)
handle->repeater_flag = false;
handle->update_stream = false;
handle->last_msg_sent = 0;
+ handle->last_msg = INVALID_MESSAGE_ID;
handle->hdcp_timeout = 0;
handle->timeout_left = 0;
handle->legacy_app = false;
@@ -1750,6 +1859,7 @@ static void hdcp_lib_msg_recvd(struct hdcp_lib_handle *handle)
struct hdcp_rcvd_msg_rsp *rsp_buf;
uint32_t msglen;
char *msg = NULL;
+ uint32_t message_id_bytes = 0;
if (!handle || !handle->qseecom_handle ||
!handle->qseecom_handle->sbuf) {
@@ -1774,6 +1884,12 @@ static void hdcp_lib_msg_recvd(struct hdcp_lib_handle *handle)
goto exit;
}
+ /* If the client is DP then allocate extra byte for message ID. */
+ if (handle->device_type == HDCP_TXMTR_DP)
+ message_id_bytes = 1;
+
+ msglen += message_id_bytes;
+
msg = kzalloc(msglen, GFP_KERNEL);
if (!msg) {
mutex_unlock(&handle->msg_lock);
@@ -1781,7 +1897,13 @@ static void hdcp_lib_msg_recvd(struct hdcp_lib_handle *handle)
goto exit;
}
- memcpy(msg, handle->last_msg_recvd_buf, msglen);
+ /* copy the message id if needed */
+ if (message_id_bytes)
+ memcpy(msg, &handle->last_msg, message_id_bytes);
+
+ memcpy(msg + message_id_bytes,
+ handle->last_msg_recvd_buf,
+ handle->last_msg_recvd_len);
mutex_unlock(&handle->msg_lock);