summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Collyer <scollyer@google.com>2022-11-15 15:11:37 -0800
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-11-29 00:45:31 +0000
commit6df1ce73533c970762dfef6c878523d01648f846 (patch)
tree43cb509eb3148b625c219a1a358455847e0e358d
parent1fc2ef1334bb550a558fedf6d9ed824be3272c41 (diff)
downloadchrome-ec-6df1ce73533c970762dfef6c878523d01648f846.tar.gz
zephyr: test: Add tests for USB_Enter/DATA_RESET messages
This CL adds support for USB_Enter and DATA_RESET messages to the tcpc emmulator. In addition it adds a test suite for USB4 mode. The usbc_tbt_mode test suite was used as a starting reference. BUG=b:260095516 BRANCH=none TEST=manual twister -c -v -i -s <path>/drivers/drivers.usbc_usb4_mode and verify that the tests pass. Signed-off-by: Scott Collyer <scollyer@google.com> Change-Id: I34e104a1e53b1540b20451fbd0631bbd9d42559b Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4029517 Code-Coverage: Zoss <zoss-cl-coverage@prod.google.com> Commit-Queue: Scott Collyer <scollyer@chromium.org> Tested-by: Scott Collyer <scollyer@chromium.org> Reviewed-by: Abe Levkoy <alevkoy@chromium.org>
-rw-r--r--zephyr/emul/tcpc/emul_tcpci_partner_common.c36
-rw-r--r--zephyr/include/emul/tcpc/emul_tcpci_partner_common.h2
-rw-r--r--zephyr/test/drivers/CMakeLists.txt1
-rw-r--r--zephyr/test/drivers/Kconfig5
-rw-r--r--zephyr/test/drivers/testcase.yaml4
-rw-r--r--zephyr/test/drivers/usbc_usb4_mode/CMakeLists.txt5
-rw-r--r--zephyr/test/drivers/usbc_usb4_mode/src/usbc_usb4_mode.c269
7 files changed, 322 insertions, 0 deletions
diff --git a/zephyr/emul/tcpc/emul_tcpci_partner_common.c b/zephyr/emul/tcpc/emul_tcpci_partner_common.c
index cb12d37b63..0473f967dc 100644
--- a/zephyr/emul/tcpc/emul_tcpci_partner_common.c
+++ b/zephyr/emul/tcpc/emul_tcpci_partner_common.c
@@ -759,6 +759,27 @@ tcpci_partner_common_vdm_handler(struct tcpci_partner_data *data,
}
static enum tcpci_partner_handler_res
+tcpci_partner_enter_usb_handler(struct tcpci_partner_data *data,
+ const struct tcpci_emul_msg *message)
+{
+ /*
+ * Validate received Enter_USB message against EUDO contents in
+ * tcpci_partner_data.
+ *
+ * TODO(b/260095516): This support needs to be expanded to validate the
+ * message contents, in a bit field basis. Currently, using this field
+ * as simple ACCEPT/REJECT criteria. If this value is 0 (default case),
+ * then ACCEPT this message, else reject it.
+ */
+ if (data->enter_usb_accept)
+ tcpci_partner_send_control_msg(data, PD_CTRL_ACCEPT, 0);
+ else
+ tcpci_partner_send_control_msg(data, PD_CTRL_REJECT, 0);
+
+ return TCPCI_PARTNER_COMMON_MSG_HANDLED;
+}
+
+static enum tcpci_partner_handler_res
tcpci_partner_common_cable_handler(struct tcpci_partner_data *data,
const struct tcpci_emul_msg *message,
enum tcpci_msg_type sop_type)
@@ -1081,6 +1102,8 @@ tcpci_partner_common_sop_msg_handler(struct tcpci_partner_data *data,
switch (PD_HEADER_TYPE(header)) {
case PD_DATA_VENDOR_DEF:
return tcpci_partner_common_vdm_handler(data, tx_msg);
+ case PD_DATA_ENTER_USB:
+ return tcpci_partner_enter_usb_handler(data, tx_msg);
default:
/* No other common handlers for data messages */
return TCPCI_PARTNER_COMMON_MSG_NOT_HANDLED;
@@ -1160,6 +1183,18 @@ tcpci_partner_common_sop_msg_handler(struct tcpci_partner_data *data,
tcpci_partner_common_send_soft_reset(data);
return TCPCI_PARTNER_COMMON_MSG_HANDLED;
+ case PD_CTRL_DATA_RESET:
+ /*
+ * Send Accept/Reject message
+ * TODO(b/260095516): To fully exercise this code path, there
+ * needs to be a mechanism (trigger) to either accept or reject
+ * this message.
+ */
+ tcpci_partner_send_control_msg(data, PD_CTRL_ACCEPT, 0);
+ return TCPCI_PARTNER_COMMON_MSG_HANDLED;
+ case PD_CTRL_DATA_RESET_COMPLETE:
+ /* There is no expected reply message from the port parter */
+ return TCPCI_PARTNER_COMMON_MSG_HANDLED;
}
return TCPCI_PARTNER_COMMON_MSG_NOT_HANDLED;
@@ -1599,6 +1634,7 @@ void tcpci_partner_init(struct tcpci_partner_data *data, enum pd_rev_type rev)
data->identity_vdos = 0;
data->svids_vdos = 0;
data->modes_vdos = 0;
+ data->enter_usb_accept = false;
tcpci_partner_common_clear_ams_ctrl_msg(data);
diff --git a/zephyr/include/emul/tcpc/emul_tcpci_partner_common.h b/zephyr/include/emul/tcpc/emul_tcpci_partner_common.h
index d0d0a2d183..dd8909c2ca 100644
--- a/zephyr/include/emul/tcpc/emul_tcpci_partner_common.h
+++ b/zephyr/include/emul/tcpc/emul_tcpci_partner_common.h
@@ -187,6 +187,8 @@ struct tcpci_partner_data {
*/
bool have_response[PD_BATT_MAX];
} battery_capabilities;
+ /* Used to control accept/reject for partner port of Enter_USB msg */
+ bool enter_usb_accept;
/*
* Cable which is "plugged in" to this port partner
diff --git a/zephyr/test/drivers/CMakeLists.txt b/zephyr/test/drivers/CMakeLists.txt
index 3a1390fddf..7c7ff22b31 100644
--- a/zephyr/test/drivers/CMakeLists.txt
+++ b/zephyr/test/drivers/CMakeLists.txt
@@ -41,6 +41,7 @@ add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_USBC_CONSOLE_PD usbc_console_pd)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_USBC_CTVPD usbc_ctvpd)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_USBC_SVDM_DFP_ONLY usbc_svdm_dfp_only)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_USBC_TBT_MODE usbc_tbt_mode)
+add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_USBC_USB4_MODE usbc_usb4_mode)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_USBC_VCONN_SWAP usbc_vconn_swap)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_USBC_OCP usbc_ocp)
add_subdirectory_ifdef(CONFIG_LINK_TEST_SUITE_USBC_PPC usbc_ppc)
diff --git a/zephyr/test/drivers/Kconfig b/zephyr/test/drivers/Kconfig
index 0994444f23..8cc1131193 100644
--- a/zephyr/test/drivers/Kconfig
+++ b/zephyr/test/drivers/Kconfig
@@ -118,6 +118,11 @@ config LINK_TEST_SUITE_USBC_SVDM_DFP_ONLY
config LINK_TEST_SUITE_USBC_TBT_MODE
bool "Link and test the usbc_tbt_mode tests"
+config LINK_TEST_SUITE_USBC_USB4_MODE
+ bool "Link and test the usbc_usb4_mode tests"
+ help
+ Include the usbc_usb4 test suite in the binary.
+
config LINK_TEST_SUITE_USBC_VCONN_SWAP
bool "Link and test the usbc_vconn_swap tests"
help
diff --git a/zephyr/test/drivers/testcase.yaml b/zephyr/test/drivers/testcase.yaml
index f74289086a..896562f4f8 100644
--- a/zephyr/test/drivers/testcase.yaml
+++ b/zephyr/test/drivers/testcase.yaml
@@ -228,6 +228,10 @@ tests:
drivers.usbc_tbt_mode:
extra_configs:
- CONFIG_LINK_TEST_SUITE_USBC_TBT_MODE=y
+ drivers.usbc_usb4_mode:
+ extra_configs:
+ - CONFIG_LINK_TEST_SUITE_USBC_USB4_MODE=y
+ - CONFIG_PLATFORM_EC_USB_PD_DATA_RESET_MSG=y
drivers.usbc_vconn_swap:
extra_configs:
- CONFIG_LINK_TEST_SUITE_USBC_VCONN_SWAP=y
diff --git a/zephyr/test/drivers/usbc_usb4_mode/CMakeLists.txt b/zephyr/test/drivers/usbc_usb4_mode/CMakeLists.txt
new file mode 100644
index 0000000000..dcf03ae2f6
--- /dev/null
+++ b/zephyr/test/drivers/usbc_usb4_mode/CMakeLists.txt
@@ -0,0 +1,5 @@
+# Copyright 2022 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+target_sources(app PRIVATE src/usbc_usb4_mode.c)
diff --git a/zephyr/test/drivers/usbc_usb4_mode/src/usbc_usb4_mode.c b/zephyr/test/drivers/usbc_usb4_mode/src/usbc_usb4_mode.c
new file mode 100644
index 0000000000..536f41577e
--- /dev/null
+++ b/zephyr/test/drivers/usbc_usb4_mode/src/usbc_usb4_mode.c
@@ -0,0 +1,269 @@
+/* Copyright 2022 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "ec_commands.h"
+#include "ec_tasks.h"
+#include "emul/tcpc/emul_tcpci.h"
+#include "emul/tcpc/emul_tcpci_partner_snk.h"
+#include "host_command.h"
+#include "test/drivers/stubs.h"
+#include "tcpm/tcpci.h"
+#include "test/drivers/utils.h"
+#include "test/drivers/test_state.h"
+#include "usb_pd_vdo.h"
+
+#include <zephyr/kernel.h>
+#include <zephyr/sys/byteorder.h>
+#include <zephyr/ztest.h>
+
+#include <stdint.h>
+
+#define TEST_PORT USBC_PORT_C0
+/* Remove polarity for any mux checks */
+#define USB_MUX_CHECK_MASK ~USB_PD_MUX_POLARITY_INVERTED
+
+struct usbc_usb4_mode_fixture {
+ const struct emul *tcpci_emul;
+ const struct emul *charger_emul;
+ struct tcpci_partner_data partner;
+ struct tcpci_snk_emul_data snk_ext;
+};
+
+/* Passive USB4 cable */
+struct tcpci_cable_data passive_usb4 = {
+ .identity_vdm[VDO_INDEX_HDR] =
+ VDO(USB_SID_PD, /* structured VDM */ true,
+ VDO_CMDT(CMDT_RSP_ACK) | CMD_DISCOVER_IDENT),
+ .identity_vdm[VDO_INDEX_IDH] = VDO_IDH(
+ /* USB host */ false, /* USB device */ false, IDH_PTYPE_PCABLE,
+ /* modal operation */ false, USB_VID_GOOGLE),
+ .identity_vdm[VDO_INDEX_CSTAT] = 0,
+ .identity_vdm[VDO_INDEX_PRODUCT] = VDO_PRODUCT(0x1234, 0xABCD),
+ .identity_vdm[VDO_INDEX_PTYPE_CABLE1] =
+ VDO_REV30_PASSIVE(USB_R30_SS_U40_GEN3, USB_VBUS_CUR_3A,
+ USB_REV30_LATENCY_1m, USB_REV30_TYPE_C),
+ .identity_vdos = VDO_INDEX_PTYPE_CABLE1 + 1,
+
+};
+
+static void add_sop_vdm_responses(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_REV30(
+ /* USB host */ false, /* USB device */ true,
+ /* ptype_u */ IDH_PTYPE_HUB, /* modal */ false,
+ /* ptype_d */ IDH_PTYPE_UNDEF, /* ctype */ USB_TYPEC_RECEPTACLE,
+ USB_VID_GOOGLE);
+ partner->identity_vdm[VDO_INDEX_CSTAT] = 0;
+ partner->identity_vdm[VDO_INDEX_PRODUCT] = VDO_PRODUCT(0x1234, 0x5678);
+ partner->identity_vdm[VDO_INDEX_PTYPE_UFP1_VDO] = VDO_UFP1(
+ /* capability */ (VDO_UFP1_CAPABILITY_USB20 |
+ VDO_UFP1_CAPABILITY_USB32 |
+ VDO_UFP1_CAPABILITY_USB4),
+ /* ctype */ USB_TYPEC_RECEPTACLE,
+ /* alt modes */ VDO_UFP1_ALT_MODE_TBT3,
+ /* speed */ USB_R30_SS_U40_GEN3);
+ partner->identity_vdm[VDO_INDEX_PTYPE_UFP2_VDO] = 0;
+ partner->identity_vdos = VDO_INDEX_PTYPE_UFP2_VDO + 1;
+
+ /* Add Discover SVIDs response */
+ /*
+ * TODO(b/260095516): USB4 entry does not depend on the contents of
+ * Discover SVIDs, but a valid Discover SVID response needs to to exist
+ * to ensure that discovery completes as that's a dependency in the DPM
+ * module to attempt either Enter_USB or DATA_RESET.
+ */
+ 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_VID_INTEL, 0);
+ partner->svids_vdos = VDO_INDEX_HDR + 2;
+
+ /* Add Discover Modes response */
+ /*
+ * TODO(b/260095516): USB4 entry does not depend on the contents of
+ * Discover Modes, but a valid Discover Modes response needs to to exist
+ * to ensure that discovery completes as that's a dependency in the DPM
+ * module to attempt either Enter_USB or DATA_RESET.
+ */
+ /* Support one mode for TBT (Intel) VID */
+ partner->modes_vdm[VDO_INDEX_HDR] =
+ VDO(USB_VID_INTEL, /* structured VDM */ true,
+ VDO_CMDT(CMDT_RSP_ACK) | CMD_DISCOVER_MODES);
+ partner->modes_vdm[VDO_INDEX_HDR + 1] = TBT_ALTERNATE_MODE;
+ partner->modes_vdos = VDO_INDEX_HDR + 2;
+}
+
+static void verify_cable_found(struct tcpci_cable_data *cable)
+{
+ uint8_t response_buffer[EC_LPC_HOST_PACKET_SIZE];
+ struct ec_response_typec_discovery *discovery =
+ (struct ec_response_typec_discovery *)response_buffer;
+
+ host_cmd_typec_discovery(TEST_PORT, TYPEC_PARTNER_SOP_PRIME,
+ response_buffer, sizeof(response_buffer));
+
+ /* The host command does not count the VDM header in identity_count. */
+ zassert_equal(discovery->identity_count, cable->identity_vdos - 1,
+ "Expected %d identity VDOs, got %d",
+ cable->identity_vdos - 1, discovery->identity_count);
+ zassert_mem_equal(discovery->discovery_vdo, cable->identity_vdm + 1,
+ discovery->identity_count *
+ sizeof(*discovery->discovery_vdo),
+ "Discovered SOP' identity ACK did not match");
+}
+
+static void *usbc_usb4_mode_setup(void)
+{
+ static struct usbc_usb4_mode_fixture fixture;
+ struct tcpci_partner_data *partner = &fixture.partner;
+ struct tcpci_snk_emul_data *snk_ext = &fixture.snk_ext;
+
+ tcpci_partner_init(partner, PD_REV30);
+ partner->extensions = tcpci_snk_emul_init(snk_ext, partner, NULL);
+
+ /* Get references for the emulators */
+ fixture.tcpci_emul = EMUL_DT_GET(DT_NODELABEL(tcpci_emul));
+ fixture.charger_emul = EMUL_DT_GET(DT_NODELABEL(isl923x_emul));
+
+ add_sop_vdm_responses(partner);
+ /* Note: cable behavior will vary by test case */
+
+ return &fixture;
+}
+
+static void usbc_usb4_mode_before(void *data)
+{
+ struct usbc_usb4_mode_fixture *fix = data;
+
+ /* Set chipset to ON, this will set TCPM to DRP */
+ test_set_chipset_to_s0();
+
+ /* TODO(b/214401892): Check why need to give TCPM time to spin */
+ k_sleep(K_SECONDS(1));
+
+ /* Enable message logging after TCPM spin */
+ tcpci_partner_common_enable_pd_logging(&fix->partner, true);
+
+ /* Initialize parter port Enter_USB msg accept/reject state */
+ fix->partner.enter_usb_accept = false;
+}
+
+static void usbc_usb4_mode_after(void *data)
+{
+ struct usbc_usb4_mode_fixture *fix = data;
+
+ disconnect_sink_from_port(fix->tcpci_emul);
+ tcpci_partner_common_enable_pd_logging(&fix->partner, false);
+ tcpci_partner_common_clear_logged_msgs(&fix->partner);
+}
+
+ZTEST_F(usbc_usb4_mode, verify_discovery)
+{
+ uint8_t response_buffer[EC_LPC_HOST_PACKET_SIZE];
+ struct ec_response_typec_discovery *discovery =
+ (struct ec_response_typec_discovery *)response_buffer;
+
+ connect_sink_to_port(&fixture->partner, fixture->tcpci_emul,
+ fixture->charger_emul);
+
+ host_cmd_typec_discovery(TEST_PORT, TYPEC_PARTNER_SOP, response_buffer,
+ sizeof(response_buffer));
+
+ /* The host command does not count the VDM header in identity_count. */
+ zassert_equal(discovery->identity_count,
+ fixture->partner.identity_vdos - 1,
+ "Expected %d identity VDOs, got %d",
+ fixture->partner.identity_vdos - 1,
+ discovery->identity_count);
+ zassert_mem_equal(
+ discovery->discovery_vdo, fixture->partner.identity_vdm + 1,
+ discovery->identity_count * sizeof(*discovery->discovery_vdo),
+ "Discovered SOP identity ACK did not match");
+}
+
+/* Without an e-marked cable, USB4 mode cannot be entered */
+ZTEST_F(usbc_usb4_mode, verify_usb4_entry_fail)
+{
+ struct ec_response_typec_status status;
+
+ fixture->partner.cable = NULL;
+ connect_sink_to_port(&fixture->partner, fixture->tcpci_emul,
+ fixture->charger_emul);
+
+ status = host_cmd_typec_status(TEST_PORT);
+ zassert_equal((status.mux_state & USB_MUX_CHECK_MASK),
+ USB_PD_MUX_USB_ENABLED, "Unexpected starting mux: 0x%02x",
+ status.mux_state);
+
+ host_cmd_typec_control_enter_mode(TEST_PORT, TYPEC_MODE_USB4);
+ k_sleep(K_SECONDS(1));
+
+ /*
+ * TODO(b/260095516): Notify the AP that the enter mode request
+ * failed.
+ */
+
+ status = host_cmd_typec_status(TEST_PORT);
+ zassert_equal((status.mux_state & USB_MUX_CHECK_MASK),
+ USB_PD_MUX_USB_ENABLED, "Failed to see USB still set");
+ zassert_not_equal((status.mux_state & USB_MUX_CHECK_MASK),
+ USB_PD_MUX_USB4_ENABLED, "Unexpected USB4 mode set");
+}
+
+/* With passive e-marked cable, USB4 mode can be entered on SOP only */
+ZTEST_F(usbc_usb4_mode, verify_usb4_passive_entry_exit)
+{
+ struct ec_response_typec_status status;
+
+ fixture->partner.cable = &passive_usb4;
+ connect_sink_to_port(&fixture->partner, fixture->tcpci_emul,
+ fixture->charger_emul);
+
+ /* Instruct partner port to accept Enter_USB message */
+ fixture->partner.enter_usb_accept = true;
+
+ /* Verify that we properly identify a USB4 capable passive cable */
+ verify_cable_found(fixture->partner.cable);
+
+ status = host_cmd_typec_status(TEST_PORT);
+ zassert_equal((status.mux_state & USB_MUX_CHECK_MASK),
+ USB_PD_MUX_USB_ENABLED, "Unexpected starting mux: 0x%02x",
+ status.mux_state);
+
+ host_cmd_typec_control_enter_mode(TEST_PORT, TYPEC_MODE_USB4);
+ k_sleep(K_SECONDS(2));
+
+ /*
+ * TODO(b/260095516): Notify the AP that the enter mode request
+ * succeeded.
+ */
+
+ /* Verify we entered USB4 mode */
+ status = host_cmd_typec_status(TEST_PORT);
+ zassert_equal((status.mux_state & USB_MUX_CHECK_MASK),
+ USB_PD_MUX_USB4_ENABLED, "Failed to see USB4 set");
+
+ /* Exit modes now */
+ host_cmd_typec_control_exit_modes(TEST_PORT);
+ k_sleep(K_SECONDS(1));
+
+ /* Verify that USB4 mode was exited by checking current mux state. */
+ status = host_cmd_typec_status(TEST_PORT);
+ zassert_equal((status.mux_state & USB_MUX_CHECK_MASK),
+ USB_PD_MUX_USB_ENABLED, "Failed to see USB set");
+}
+
+/*
+ * TODO(b/260095516): This test suite is only testing the default good case, and
+ * one error case where the cable doesn't support USB4. This suite needs to be
+ * expanded to cover cases where the port partner rejects Enter_USB along with
+ * active cable cases.
+ */
+ZTEST_SUITE(usbc_usb4_mode, drivers_predicate_post_main, usbc_usb4_mode_setup,
+ usbc_usb4_mode_before, usbc_usb4_mode_after, NULL);