[PATCH 16/43] misc/mei/hdcp: Verify L_prime

Ramalingam C
2018-02-14T14:20:24Z

Request to ME to verify the LPrime received from HDCP sink.

On Success, ME FW will verify the received Lprime by calculating and
comparing with L.

This represents the completion of Locality Check.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
drivers/misc/mei/mei_hdcp.c | 65 +++++++++++++++++++++++++++++++++++++++++++++
include/linux/mei_hdcp.h | 8 ++++++
2 files changed, 73 insertions(+)

diff --git a/drivers/misc/mei/mei_hdcp.c b/drivers/misc/mei/mei_hdcp.c
index 5f0c56a1e51b..828dcce56b49 100644
--- a/drivers/misc/mei/mei_hdcp.c
+++ b/drivers/misc/mei/mei_hdcp.c
@@ -403,6 +403,71 @@ int mei_initiate_locality_check(struct mei_hdcp_data *data,
}
EXPORT_SYMBOL(mei_initiate_locality_check);

+/**
+ * mei_verify_lprime:
+ * Function to verify lprime.
+ *
+ * @data : Intel HW specific Data
+ * @rx_lprime : Pointer for LC_Send_L_prime
+ *
+ * Returns 0 on Success, <0 on Failure
+ */
+int mei_verify_lprime(struct mei_hdcp_data *data,
+ struct hdcp2_lc_send_lprime *rx_lprime)
+{
+ struct wired_cmd_validate_locality_in verify_lprime_in = { { 0 } };
+ struct wired_cmd_validate_locality_out verify_lprime_out = { { 0 } };
+ enum me_status status;
+ struct device *dev;
+ ssize_t byte;
+
+ if (!data || !rx_lprime)
+ return -EINVAL;
+
+ /* check for the mei_device enabled or not */
+ if (!mei_cldev_active_and_enabled(data->cldev))
+ return -ENODEV;
+
+ dev = &data->cldev->dev;
+
+ verify_lprime_in.header.api_version = HDCP_API_VERSION;
+ verify_lprime_in.header.command_id = WIRED_VALIDATE_LOCALITY;
+ verify_lprime_in.header.status = ME_HDCP_STATUS_SUCCESS;
+ verify_lprime_in.header.buffer_len =
+ WIRED_CMD_BUF_LEN_VALIDATE_LOCALITY_IN;
+
+ verify_lprime_in.port.integrated_port_type = data->port_type;
+ verify_lprime_in.port.physical_port = data->port;
+
+ memcpy(verify_lprime_in.l_prime, rx_lprime->l_prime,
+ sizeof(rx_lprime->l_prime));
+
+ /* Request to ME */
+ byte = mei_cldev_send(data->cldev, (u8 *)&verify_lprime_in,
+ sizeof(verify_lprime_in));
+ if (byte < 0) {
+ dev_err(dev, "mei_cldev_send failed. %d\n", (int)byte);
+ return byte;
+ }
+
+ /* Response from ME */
+ byte = mei_cldev_recv(data->cldev, (u8 *)&verify_lprime_out,
+ sizeof(verify_lprime_out));
+ if (byte < 0) {
+ dev_err(dev, "mei_cldev_recv failed. %d\n", (int)byte);
+ return byte;
+ }
+
+ status = (enum me_status)verify_lprime_out.header.status;
+ if (status != ME_HDCP_STATUS_SUCCESS) {
+ dev_err(dev, "ME cmd 0x%08X failed. status: 0x%X\n",
+ WIRED_VALIDATE_LOCALITY, status);
+ return -1;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(mei_verify_lprime);
+
static int mei_hdcp_probe(struct mei_cl_device *cldev,
const struct mei_cl_device_id *id)
{
diff --git a/include/linux/mei_hdcp.h b/include/linux/mei_hdcp.h
index fd8a26dddacb..d8c2b440cd81 100644
--- a/include/linux/mei_hdcp.h
+++ b/include/linux/mei_hdcp.h
@@ -117,6 +117,8 @@ int mei_store_pairing_info(struct mei_hdcp_data *data,
struct hdcp2_ake_send_pairing_info *pairing_info);
int mei_initiate_locality_check(struct mei_hdcp_data *data,
struct hdcp2_lc_init *lc_init_data);
+int mei_verify_lprime(struct mei_hdcp_data *data,
+ struct hdcp2_lc_send_lprime *rx_lprime);
#else
static inline
int mei_hdcp_cldev_get_reference(void *client_data,
@@ -164,5 +166,11 @@ int mei_initiate_locality_check(struct mei_hdcp_data *data,
{
return -ENODEV;
}
+static inline
+int mei_verify_lprime(struct mei_hdcp_data *data,
+ struct hdcp2_lc_send_lprime *rx_lprime)
+{
+ return -ENODEV;
+}
#endif /* defined (CONFIG_INTEL_MEI_HDCP) */
#endif /* defined (_LINUX_MEI_HDCP_H) */