diff options
author | Diana Z <dzigterman@chromium.org> | 2022-11-22 08:15:42 -0700 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-12-13 22:43:33 +0000 |
commit | 74cf8aab5c3356574e3dadc89c67041ed8634811 (patch) | |
tree | 75d80746b4fad09299b454dd1f22ab8f7e915062 | |
parent | 0085c1c5450c7992c2a5111414741d711a14ec65 (diff) | |
download | chrome-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.c | 191 |
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"); +} |