summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiana Z <dzigterman@chromium.org>2022-11-22 08:15:42 -0700
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-12-13 22:43:33 +0000
commit74cf8aab5c3356574e3dadc89c67041ed8634811 (patch)
tree75d80746b4fad09299b454dd1f22ab8f7e915062
parent0085c1c5450c7992c2a5111414741d711a14ec65 (diff)
downloadchrome-ec-74cf8aab5c3356574e3dadc89c67041ed8634811.tar.gz
Zephyr test: Add tests for AP VDM replies
Add tests verifying we get the expected results for both ACK and NAK commands, as well as some error conditions. This also corrects a logical error in the previous tests for the VDM_REQ host command, which had not correctly verified the message passed through. BRANCH=None BUG=b:208884535 TEST=./twister -T ./zephyr/test Signed-off-by: Diana Z <dzigterman@chromium.org> Change-Id: I763d0270c7a38b92948ce1b0c2c7fc0dafb07150 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4048914 Code-Coverage: Zoss <zoss-cl-coverage@prod.google.com> Reviewed-by: Abe Levkoy <alevkoy@chromium.org>
-rw-r--r--zephyr/test/drivers/ap_vdm_control/src/ap_vdm_control.c191
1 files changed, 188 insertions, 3 deletions
diff --git a/zephyr/test/drivers/ap_vdm_control/src/ap_vdm_control.c b/zephyr/test/drivers/ap_vdm_control/src/ap_vdm_control.c
index fe7dab88f4..2dc81fedac 100644
--- a/zephyr/test/drivers/ap_vdm_control/src/ap_vdm_control.c
+++ b/zephyr/test/drivers/ap_vdm_control/src/ap_vdm_control.c
@@ -41,6 +41,44 @@ struct tcpci_cable_data passive_usb3 = {
};
+static void add_dp_discovery(struct tcpci_partner_data *partner)
+{
+ /* Add Discover Identity response */
+ partner->identity_vdm[VDO_INDEX_HDR] =
+ VDO(USB_SID_PD, /* structured VDM */ true,
+ VDO_CMDT(CMDT_RSP_ACK) | CMD_DISCOVER_IDENT);
+ partner->identity_vdm[VDO_INDEX_IDH] = VDO_IDH(
+ /* USB host */ false, /* USB device */ true, IDH_PTYPE_HUB,
+ /* modal operation */ true, USB_VID_GOOGLE);
+ partner->identity_vdm[VDO_INDEX_CSTAT] = 0;
+ partner->identity_vdm[VDO_INDEX_PRODUCT] = VDO_PRODUCT(0x1234, 0x5678);
+ /* Hardware version 1, firmware version 2 */
+ partner->identity_vdm[VDO_INDEX_PTYPE_UFP1_VDO] = VDO_UFP1(
+ (VDO_UFP1_CAPABILITY_USB20 | VDO_UFP1_CAPABILITY_USB32),
+ USB_TYPEC_RECEPTACLE, VDO_UFP1_ALT_MODE_RECONFIGURE,
+ USB_R30_SS_U32_U40_GEN2);
+ partner->identity_vdos = VDO_INDEX_PTYPE_UFP1_VDO + 1;
+
+ /* Add Discover Modes response */
+ /* Support one mode for DisplayPort VID.*/
+ partner->modes_vdm[VDO_INDEX_HDR] =
+ VDO(USB_SID_DISPLAYPORT, /* structured VDM */ true,
+ VDO_CMDT(CMDT_RSP_ACK) | CMD_DISCOVER_MODES);
+ partner->modes_vdm[VDO_INDEX_HDR + 1] =
+ VDO_MODE_DP(MODE_DP_PIN_C | MODE_DP_PIN_D, 0, 1,
+ CABLE_RECEPTACLE, MODE_DP_V13, MODE_DP_SNK);
+ partner->modes_vdos = VDO_INDEX_HDR + 2;
+
+ /* Add Discover SVIDs response */
+ /* Support DisplayPort VID. */
+ partner->svids_vdm[VDO_INDEX_HDR] =
+ VDO(USB_SID_PD, /* structured VDM */ true,
+ VDO_CMDT(CMDT_RSP_ACK) | CMD_DISCOVER_SVID);
+ partner->svids_vdm[VDO_INDEX_HDR + 1] =
+ VDO_SVID(USB_SID_DISPLAYPORT, 0);
+ partner->svids_vdos = VDO_INDEX_HDR + 2;
+}
+
static void verify_vdm_req(struct ap_vdm_control_fixture *fixture,
struct typec_vdm_req *req)
{
@@ -69,8 +107,8 @@ static void verify_vdm_req(struct ap_vdm_control_fixture *fixture,
continue;
/* We have a VDM, check entry we're interested in */
- if (memcmp(msg->buf, req->vdm_data,
- req->vdm_data_objects * sizeof(uint32_t))) {
+ if (memcmp(msg->buf + 2, req->vdm_data,
+ req->vdm_data_objects * sizeof(uint32_t)) == 0) {
message_seen = true;
break;
}
@@ -87,7 +125,6 @@ static void *ap_vdm_control_setup(void)
tcpci_partner_init(partner, PD_REV30);
partner->extensions = tcpci_src_emul_init(src_ext, partner, NULL);
- partner->cable = &passive_usb3;
/* Get references for the emulators */
fixture.tcpci_emul = EMUL_DT_GET(DT_NODELABEL(tcpci_emul));
@@ -99,10 +136,15 @@ static void *ap_vdm_control_setup(void)
static void ap_vdm_control_before(void *data)
{
struct ap_vdm_control_fixture *fix = data;
+ struct tcpci_partner_data *partner = &fix->partner;
/* Set chipset on so the "AP" is on to give us commands */
test_set_chipset_to_s0();
+ /* Set up the partner as DP-capable with a passive cable */
+ add_dp_discovery(partner);
+ partner->cable = &passive_usb3;
+
/* Connect our port partner */
connect_source_to_port(&fix->partner, &fix->src_ext, 0, fix->tcpci_emul,
fix->charger_emul);
@@ -128,6 +170,7 @@ ZTEST_F(ap_vdm_control, test_feature_present)
"Failed to see feature present");
}
+/* TYPEC_CONTROL_COMMAND_SEND_VDM_REQ tests */
ZTEST_F(ap_vdm_control, test_send_vdm_req_bad_port)
{
struct ec_params_typec_control params = {
@@ -263,3 +306,145 @@ ZTEST_F(ap_vdm_control, test_send_vdm_req_in_progress)
zassert_equal(host_command_process(&args), EC_RES_BUSY,
"Failed to see busy");
}
+
+/* EC_CMD_TYPEC_VDM_RESPONSE tests */
+ZTEST_F(ap_vdm_control, test_vdm_response_ack)
+{
+ struct ec_response_typec_status status;
+ struct ec_response_typec_vdm_response vdm_resp;
+ uint32_t vdm_req_header = VDO(USB_SID_PD, 1, CMD_DISCOVER_IDENT);
+ struct typec_vdm_req req = {
+ .vdm_data = { vdm_req_header },
+ .vdm_data_objects = 1,
+ .partner_type = TYPEC_PARTNER_SOP,
+ };
+
+ host_cmd_typec_control_vdm_req(TEST_PORT, req);
+ k_sleep(K_SECONDS(1));
+
+ /* Look for our notification and reply */
+ status = host_cmd_typec_status(TEST_PORT);
+ zassert_true(status.events & PD_STATUS_EVENT_VDM_REQ_REPLY,
+ "Failed to see VDM ACK event");
+
+ vdm_resp = host_cmd_typec_vdm_response(TEST_PORT);
+ zassert_equal(vdm_resp.partner_type, req.partner_type,
+ "Failed to see correct partner");
+ zassert_equal(vdm_resp.vdm_data_objects, fixture->partner.identity_vdos,
+ "Failed to see correct VDO num");
+ zassert_equal(memcmp(vdm_resp.vdm_response,
+ fixture->partner.identity_vdm,
+ vdm_resp.vdm_data_objects * sizeof(uint32_t)),
+ 0, "Failed to see correct VDM contents");
+}
+
+ZTEST_F(ap_vdm_control, test_vdm_request_nak)
+{
+ struct ec_response_typec_status status;
+ struct ec_response_typec_vdm_response vdm_resp;
+ uint32_t vdm_req_header = VDO(USB_SID_DISPLAYPORT, 1, CMD_ENTER_MODE);
+ struct typec_vdm_req req = {
+ .vdm_data = { vdm_req_header },
+ .vdm_data_objects = 1,
+ .partner_type = TYPEC_PARTNER_SOP,
+ };
+
+ /* Add DisplayPort EnterMode NAK */
+ fixture->partner.enter_mode_vdm[VDO_INDEX_HDR] =
+ VDO(USB_SID_DISPLAYPORT, /* structured VDM */ true,
+ VDO_CMDT(CMDT_RSP_NAK) | CMD_ENTER_MODE);
+ fixture->partner.enter_mode_vdos = VDO_INDEX_HDR + 1;
+
+ host_cmd_typec_control_vdm_req(TEST_PORT, req);
+ k_sleep(K_SECONDS(1));
+
+ /* Look for our notification and reply */
+ status = host_cmd_typec_status(TEST_PORT);
+ zassert_true(status.events & PD_STATUS_EVENT_VDM_REQ_REPLY,
+ "Failed to see VDM NAK event");
+
+ vdm_resp = host_cmd_typec_vdm_response(TEST_PORT);
+ zassert_equal(vdm_resp.partner_type, req.partner_type,
+ "Failed to see correct partner");
+ zassert_equal(vdm_resp.vdm_data_objects,
+ fixture->partner.enter_mode_vdos,
+ "Failed to see correct VDO num");
+ zassert_equal(memcmp(vdm_resp.vdm_response,
+ fixture->partner.enter_mode_vdm,
+ vdm_resp.vdm_data_objects * sizeof(uint32_t)),
+ 0, "Failed to see correct VDM contents");
+}
+
+ZTEST_F(ap_vdm_control, test_vdm_request_failed)
+{
+ struct ec_response_typec_status status;
+ struct ec_response_typec_vdm_response vdm_resp;
+ struct ec_params_typec_status params = { .port = TEST_PORT };
+ struct host_cmd_handler_args args = BUILD_HOST_COMMAND(
+ EC_CMD_TYPEC_VDM_RESPONSE, 0, vdm_resp, params);
+
+ uint32_t vdm_req_header = VDO(USB_SID_DISPLAYPORT, 1, CMD_ENTER_MODE);
+ struct typec_vdm_req req = {
+ .vdm_data = { vdm_req_header },
+ .vdm_data_objects = 1,
+ .partner_type = TYPEC_PARTNER_SOP,
+ };
+
+ /* Do not advertise an EnterMode response */
+ fixture->partner.enter_mode_vdos = 0;
+
+ host_cmd_typec_control_vdm_req(TEST_PORT, req);
+ k_sleep(K_SECONDS(1));
+
+ /* Look for our notification and lack of reply */
+ status = host_cmd_typec_status(TEST_PORT);
+ zassert_true(status.events & PD_STATUS_EVENT_VDM_REQ_FAILED,
+ "Failed to see notice of no reply");
+
+ zassert_equal(host_command_process(&args), EC_RES_UNAVAILABLE,
+ "Failed to get unavailable");
+}
+
+ZTEST_F(ap_vdm_control, test_vdm_request_bad_port)
+{
+ struct ec_response_typec_vdm_response vdm_resp;
+ struct ec_params_typec_status params = { .port = 88 };
+ struct host_cmd_handler_args args = BUILD_HOST_COMMAND(
+ EC_CMD_TYPEC_VDM_RESPONSE, 0, vdm_resp, params);
+
+ zassert_equal(host_command_process(&args), EC_RES_INVALID_PARAM,
+ "Failed to see bad port");
+}
+
+ZTEST_F(ap_vdm_control, test_vdm_request_in_progress)
+{
+ struct ec_response_typec_vdm_response vdm_resp;
+ struct ec_params_typec_status params = { .port = TEST_PORT };
+ struct host_cmd_handler_args args = BUILD_HOST_COMMAND(
+ EC_CMD_TYPEC_VDM_RESPONSE, 0, vdm_resp, params);
+
+ uint32_t vdm_req_header = VDO(USB_SID_PD, 1, CMD_DISCOVER_IDENT);
+ struct typec_vdm_req req = {
+ .vdm_data = { vdm_req_header },
+ .vdm_data_objects = 1,
+ .partner_type = TYPEC_PARTNER_SOP,
+ };
+
+ host_cmd_typec_control_vdm_req(TEST_PORT, req);
+
+ /* Give no processing time and immediately ask for our result */
+ zassert_equal(host_command_process(&args), EC_RES_BUSY,
+ "Failed to see busy");
+}
+
+ZTEST_F(ap_vdm_control, test_vdm_request_no_send)
+{
+ struct ec_response_typec_vdm_response vdm_resp;
+ struct ec_params_typec_status params = { .port = TEST_PORT };
+ struct host_cmd_handler_args args = BUILD_HOST_COMMAND(
+ EC_CMD_TYPEC_VDM_RESPONSE, 0, vdm_resp, params);
+
+ /* Check for an error on a fresh connection with no VDM REQ sent */
+ zassert_equal(host_command_process(&args), EC_RES_UNAVAILABLE,
+ "Failed to see no message ready");
+}