[v7,32/39] misc/mei/hdcp: Repeater topology verification and ack

Submitted by Ramalingam C on Sept. 27, 2018, 6:55 a.m.

Details

Message ID 1538031330-21040-33-git-send-email-ramalingam.c@intel.com
State New
Headers show
Series "drm/i915: Implement HDCP2.2" ( rev: 9 ) in Intel GFX

Not browsing as part of any series.

Commit Message

Ramalingam C Sept. 27, 2018, 6:55 a.m.
Request ME to verify the downstream topology information received.

ME FW will validate the Repeaters receiver id list and
downstream topology.

On Success ME FW will provide the Least Significant
128bits of VPrime, which forms the repeater ack.

v2:
  Rebased.
v3:
  cldev is passed as first parameter [Tomas]
  Redundant comments and cast are removed [Tomas]
v4:
  %zd for ssize_t [Alexander]
  %s/return -1/return -EIO [Alexander]
  Style and typos fixed [Uma]
v5:
  Rebased.
v6:
  No change.
v7:
  Rebasing.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
---
 drivers/misc/mei/hdcp/mei_hdcp.c | 77 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 76 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c
index 59ef9086cce4..2911fb6e8ed3 100644
--- a/drivers/misc/mei/hdcp/mei_hdcp.c
+++ b/drivers/misc/mei/hdcp/mei_hdcp.c
@@ -459,6 +459,80 @@  static int mei_get_session_key(struct mei_cl_device *cldev,
 	return 0;
 }
 
+/*
+ * mei_repeater_check_flow_prepare_ack:
+ *	Function to validate the Downstream topology and prepare rep_ack.
+ *
+ * cldev		: Pointer for mei client device
+ * data			: Intel HW specific Data
+ * rep_topology		: Pointer for Receiver Id List to be validated.
+ * rep_send_ack		: Pointer for repeater ack
+ *
+ * Returns 0 on Success, <0 on Failure
+ */
+static int
+mei_repeater_check_flow_prepare_ack(struct mei_cl_device *cldev,
+				    struct mei_hdcp_data *data,
+				    struct hdcp2_rep_send_receiverid_list
+							*rep_topology,
+				    struct hdcp2_rep_send_ack *rep_send_ack)
+{
+	struct wired_cmd_verify_repeater_in verify_repeater_in = { { 0 } };
+	struct wired_cmd_verify_repeater_out verify_repeater_out = { { 0 } };
+	struct device *dev;
+	ssize_t byte;
+
+	if (!rep_topology || !rep_send_ack || !data)
+		return -EINVAL;
+
+	dev = &cldev->dev;
+
+	verify_repeater_in.header.api_version = HDCP_API_VERSION;
+	verify_repeater_in.header.command_id = WIRED_VERIFY_REPEATER;
+	verify_repeater_in.header.status = ME_HDCP_STATUS_SUCCESS;
+	verify_repeater_in.header.buffer_len =
+					WIRED_CMD_BUF_LEN_VERIFY_REPEATER_IN;
+
+	verify_repeater_in.port.integrated_port_type = data->port_type;
+	verify_repeater_in.port.physical_port = data->port;
+
+	memcpy(verify_repeater_in.rx_info, rep_topology->rx_info,
+	       HDCP_2_2_RXINFO_LEN);
+	memcpy(verify_repeater_in.seq_num_v, rep_topology->seq_num_v,
+	       HDCP_2_2_SEQ_NUM_LEN);
+	memcpy(verify_repeater_in.v_prime, rep_topology->v_prime,
+	       HDCP_2_2_V_PRIME_HALF_LEN);
+	memcpy(verify_repeater_in.receiver_ids, rep_topology->receiver_ids,
+	       HDCP_2_2_RECEIVER_IDS_MAX_LEN);
+
+	byte = mei_cldev_send(cldev, (u8 *)&verify_repeater_in,
+			      sizeof(verify_repeater_in));
+	if (byte < 0) {
+		dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
+		return byte;
+	}
+
+	byte = mei_cldev_recv(cldev, (u8 *)&verify_repeater_out,
+			      sizeof(verify_repeater_out));
+	if (byte < 0) {
+		dev_dbg(dev, "mei_cldev_recv failed. %zd\n", byte);
+		return byte;
+	}
+
+	if (verify_repeater_out.header.status != ME_HDCP_STATUS_SUCCESS) {
+		dev_dbg(dev, "ME cmd 0x%08X failed. status: 0x%X\n",
+			WIRED_VERIFY_REPEATER,
+			verify_repeater_out.header.status);
+		return -EIO;
+	}
+
+	memcpy(rep_send_ack->v, verify_repeater_out.v,
+	       HDCP_2_2_V_PRIME_HALF_LEN);
+	rep_send_ack->msg_id = HDCP_2_2_REP_SEND_ACK;
+
+	return 0;
+}
+
 static __attribute__((unused))
 struct i915_hdcp_component_ops mei_hdcp_ops = {
 	.owner					= THIS_MODULE,
@@ -470,7 +544,8 @@  struct i915_hdcp_component_ops mei_hdcp_ops = {
 	.initiate_locality_check		= mei_initiate_locality_check,
 	.verify_lprime				= mei_verify_lprime,
 	.get_session_key			= mei_get_session_key,
-	.repeater_check_flow_prepare_ack	= NULL,
+	.repeater_check_flow_prepare_ack	=
+					mei_repeater_check_flow_prepare_ack,
 	.verify_mprime				= NULL,
 	.enable_hdcp_authentication		= NULL,
 	.close_hdcp_session			= NULL,