summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Hill <ecgh@chromium.org>2020-09-17 21:05:59 -0600
committerCommit Bot <commit-bot@chromium.org>2020-09-22 02:19:29 +0000
commitd03abea4c36062f922182b95e046fc6817e98eec (patch)
treecb90c1fe95ca5660d4055e0663f58b1ead034c40
parent17838629321431d8248f3ade35993a9f21242477 (diff)
downloadchrome-ec-d03abea4c36062f922182b95e046fc6817e98eec.tar.gz
test: Add test_send_caps_error to usb_pe_drp
As requested in CL:2321869 review, make a new version of test_send_caps_error that uses the external interface of the PE layer. BUG=b:161835483 BRANCH=none TEST=make run-usb_pe_drp Signed-off-by: Edward Hill <ecgh@chromium.org> Change-Id: I983b145cd1e731e844363955896898a2374a0a30 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2419834 Reviewed-by: Paul Fagerburg <pfagerburg@chromium.org> Reviewed-by: Jett Rink <jettrink@chromium.org> Commit-Queue: Paul Fagerburg <pfagerburg@chromium.org>
-rw-r--r--common/mock/usb_prl_mock.c75
-rw-r--r--common/mock/usb_tc_sm_mock.c12
-rw-r--r--common/usbc/usbc_task.c2
-rw-r--r--include/mock/usb_prl_mock.h14
-rw-r--r--include/mock/usb_tc_sm_mock.h2
-rw-r--r--test/usb_pe_drp.c90
-rw-r--r--test/usb_prl.c23
7 files changed, 183 insertions, 35 deletions
diff --git a/common/mock/usb_prl_mock.c b/common/mock/usb_prl_mock.c
index 1e9c9c9576..b682e67f80 100644
--- a/common/mock/usb_prl_mock.c
+++ b/common/mock/usb_prl_mock.c
@@ -7,6 +7,7 @@
#include <string.h>
#include "common.h"
#include "usb_emsg.h"
+#include "usb_pe_sm.h"
#include "usb_prl_sm.h"
#include "mock/usb_prl_mock.h"
@@ -14,11 +15,28 @@
struct extended_msg rx_emsg[CONFIG_USB_PD_PORT_MAX_COUNT];
struct extended_msg tx_emsg[CONFIG_USB_PD_PORT_MAX_COUNT];
+struct mock_prl_port_t {
+ enum pd_ctrl_msg_type last_ctrl_msg;
+ enum pd_data_msg_type last_data_msg_type;
+ bool message_sent;
+ bool message_received;
+ int pe_error;
+};
+
+struct mock_prl_port_t mock_prl_port[CONFIG_USB_PD_PORT_MAX_COUNT];
+
void mock_prl_reset(void)
{
+ int port;
+
/* Reset all values to 0. */
memset(rx_emsg, 0, sizeof(rx_emsg));
memset(tx_emsg, 0, sizeof(tx_emsg));
+
+ memset(mock_prl_port, 0, sizeof(mock_prl_port));
+
+ for (port = 0 ; port < CONFIG_USB_PD_PORT_MAX_COUNT ; ++port)
+ mock_prl_port[port].pe_error = -1;
}
void prl_end_ams(int port)
@@ -51,19 +69,16 @@ void prl_reset(int port)
void prl_reset_soft(int port)
{}
-static enum pd_ctrl_msg_type last_ctrl_msg[CONFIG_USB_PD_PORT_MAX_COUNT];
-static enum pd_data_msg_type last_data_msg_type[CONFIG_USB_PD_PORT_MAX_COUNT];
-
void prl_send_ctrl_msg(int port, enum tcpm_transmit_type type,
enum pd_ctrl_msg_type msg)
{
- last_ctrl_msg[port] = msg;
+ mock_prl_port[port].last_ctrl_msg = msg;
}
void prl_send_data_msg(int port, enum tcpm_transmit_type type,
enum pd_data_msg_type msg)
{
- last_data_msg_type[port] = msg;
+ mock_prl_port[port].last_data_msg_type = msg;
}
void prl_send_ext_data_msg(int port, enum tcpm_transmit_type type,
@@ -77,20 +92,62 @@ void prl_set_rev(int port, enum tcpm_transmit_type partner,
enum pd_ctrl_msg_type fake_prl_get_last_sent_ctrl_msg(int port)
{
- return last_ctrl_msg[port];
+ enum pd_ctrl_msg_type last = mock_prl_port[port].last_ctrl_msg;
+
+ fake_prl_clear_last_sent_ctrl_msg(port);
+ return last;
}
void fake_prl_clear_last_sent_ctrl_msg(int port)
{
- last_ctrl_msg[port] = 0;
+ mock_prl_port[port].last_ctrl_msg = 0;
}
enum pd_data_msg_type fake_prl_get_last_sent_data_msg_type(int port)
{
- return last_data_msg_type[port];
+ enum pd_data_msg_type last = mock_prl_port[port].last_data_msg_type;
+
+ fake_prl_clear_last_sent_data_msg(port);
+ return last;
}
void fake_prl_clear_last_sent_data_msg(int port)
{
- last_data_msg_type[port] = 0;
+ mock_prl_port[port].last_data_msg_type = 0;
+}
+
+void fake_prl_message_sent(int port)
+{
+ mock_prl_port[port].message_sent = 1;
+}
+
+void fake_prl_message_received(int port)
+{
+ mock_prl_port[port].message_received = 1;
+}
+
+void fake_prl_report_error(int port, enum pe_error e)
+{
+ mock_prl_port[port].pe_error = e;
+}
+
+void prl_run(int port, int evt, int en)
+{
+ if (mock_prl_port[port].message_sent) {
+ ccprints("message_sent");
+ pe_message_sent(port);
+ mock_prl_port[port].message_sent = 0;
+ }
+ if (mock_prl_port[port].message_received) {
+ ccprints("message_received");
+ pe_message_received(port);
+ mock_prl_port[port].message_received = 0;
+ }
+ if (mock_prl_port[port].pe_error >= 0) {
+ ccprints("pe_error %d", mock_prl_port[port].pe_error);
+ pe_report_error(port,
+ mock_prl_port[port].pe_error,
+ TCPC_TX_SOP);
+ mock_prl_port[port].pe_error = -1;
+ }
}
diff --git a/common/mock/usb_tc_sm_mock.c b/common/mock/usb_tc_sm_mock.c
index aea8076f09..dfe8eeef48 100644
--- a/common/mock/usb_tc_sm_mock.c
+++ b/common/mock/usb_tc_sm_mock.c
@@ -24,8 +24,6 @@ void mock_tc_port_reset(void)
for (port = 0 ; port < CONFIG_USB_PD_PORT_MAX_COUNT ; ++port) {
mock_tc_port[port].rev = PD_REV30;
mock_tc_port[port].pd_enable = 0;
- mock_tc_port[port].power_role = PD_ROLE_SINK;
- mock_tc_port[port].data_role = PD_ROLE_DISCONNECTED;
mock_tc_port[port].msg_tx_id = 0;
mock_tc_port[port].msg_rx_id = 0;
mock_tc_port[port].sop = TCPC_TX_INVALID;
@@ -77,16 +75,6 @@ int typec_update_cc(int port)
return EC_SUCCESS;
}
-void tc_set_data_role(int port, enum pd_data_role role)
-{
- mock_tc_port[port].data_role = role;
-}
-
-void tc_set_power_role(int port, enum pd_power_role role)
-{
- mock_tc_port[port].power_role = role;
-}
-
int tc_check_vconn_swap(int port)
{
return 0;
diff --git a/common/usbc/usbc_task.c b/common/usbc/usbc_task.c
index 7099154f38..624c55a651 100644
--- a/common/usbc/usbc_task.c
+++ b/common/usbc/usbc_task.c
@@ -104,7 +104,7 @@ static bool pd_task_loop(int port)
pe_run(port, evt, tc_get_pd_enabled(port));
/* Run protocol state machine */
- if (IS_ENABLED(CONFIG_USB_PRL_SM))
+ if (IS_ENABLED(CONFIG_USB_PRL_SM) || IS_ENABLED(CONFIG_TEST_USB_PE_SM))
prl_run(port, evt, tc_get_pd_enabled(port));
/* Run TypeC state machine */
diff --git a/include/mock/usb_prl_mock.h b/include/mock/usb_prl_mock.h
index c20498929c..5479fbd164 100644
--- a/include/mock/usb_prl_mock.h
+++ b/include/mock/usb_prl_mock.h
@@ -12,4 +12,18 @@
void mock_prl_reset(void);
+enum pd_ctrl_msg_type fake_prl_get_last_sent_ctrl_msg(int port);
+
+void fake_prl_clear_last_sent_ctrl_msg(int port);
+
+enum pd_data_msg_type fake_prl_get_last_sent_data_msg_type(int port);
+
+void fake_prl_clear_last_sent_data_msg(int port);
+
+void fake_prl_message_sent(int port);
+
+void fake_prl_message_received(int port);
+
+void fake_prl_report_error(int port, enum pe_error e);
+
#endif /* __MOCK_DP_ALT_MODE_MOCK_H */
diff --git a/include/mock/usb_tc_sm_mock.h b/include/mock/usb_tc_sm_mock.h
index 78875139ba..beefa40c74 100644
--- a/include/mock/usb_tc_sm_mock.h
+++ b/include/mock/usb_tc_sm_mock.h
@@ -13,8 +13,6 @@
struct mock_tc_port_t {
int rev;
int pd_enable;
- enum pd_power_role power_role;
- enum pd_data_role data_role;
int msg_tx_id;
int msg_rx_id;
enum tcpm_transmit_type sop;
diff --git a/test/usb_pe_drp.c b/test/usb_pe_drp.c
index b210db4ae9..8c59dcf180 100644
--- a/test/usb_pe_drp.c
+++ b/test/usb_pe_drp.c
@@ -43,12 +43,102 @@ void before_test(void)
mock_dpm_reset();
mock_dp_alt_mode_reset();
mock_prl_reset();
+
+ /* Restart the PD task and let it settle */
+ task_set_event(TASK_ID_PD_C0, TASK_EVENT_RESET_DONE, 0);
+ task_wait_event(SECOND);
+}
+
+test_static int test_send_caps_error(void)
+{
+ /* Enable PE as source, expect SOURCE_CAP. */
+ mock_pd_port[PORT0].power_role = PD_ROLE_SOURCE;
+ mock_tc_port[PORT0].pd_enable = 1;
+ task_wait_event(10 * MSEC);
+ TEST_EQ(fake_prl_get_last_sent_data_msg_type(PORT0),
+ PD_DATA_SOURCE_CAP, "%d");
+ fake_prl_message_sent(PORT0);
+ task_wait_event(10 * MSEC);
+
+ /* REQUEST 5V, expect ACCEPT, PS_RDY. */
+ rx_emsg[PORT0].header = PD_HEADER(PD_DATA_REQUEST, PD_ROLE_SINK,
+ PD_ROLE_UFP, 0,
+ 1, PD_REV30, 0);
+ rx_emsg[PORT0].len = 4;
+ *(uint32_t *)rx_emsg[PORT0].buf = RDO_FIXED(1, 500, 500, 0);
+ fake_prl_message_received(PORT0);
+ task_wait_event(10 * MSEC);
+ TEST_EQ(fake_prl_get_last_sent_ctrl_msg(PORT0),
+ PD_CTRL_ACCEPT, "%d");
+ fake_prl_message_sent(PORT0);
+ task_wait_event(10 * MSEC);
+ TEST_EQ(fake_prl_get_last_sent_ctrl_msg(PORT0),
+ PD_CTRL_PS_RDY, "%d");
+ fake_prl_message_sent(PORT0);
+ task_wait_event(30 * MSEC);
+
+ /* Expect VENDOR_DEF, reply NOT_SUPPORTED. */
+ TEST_EQ(fake_prl_get_last_sent_data_msg_type(PORT0),
+ PD_DATA_VENDOR_DEF, "%d");
+ fake_prl_message_sent(PORT0);
+ task_wait_event(10 * MSEC);
+ rx_emsg[PORT0].header = PD_HEADER(PD_CTRL_NOT_SUPPORTED, PD_ROLE_SINK,
+ PD_ROLE_UFP, 2,
+ 0, PD_REV30, 0);
+ rx_emsg[PORT0].len = 0;
+ fake_prl_message_received(PORT0);
+ task_wait_event(30 * MSEC);
+
+ /* Expect GET_SOURCE_CAP, reply NOT_SUPPORTED. */
+ TEST_EQ(fake_prl_get_last_sent_ctrl_msg(PORT0),
+ PD_CTRL_GET_SOURCE_CAP, "%d");
+ fake_prl_message_sent(PORT0);
+ task_wait_event(10 * MSEC);
+ rx_emsg[PORT0].header = PD_HEADER(PD_CTRL_NOT_SUPPORTED, PD_ROLE_SINK,
+ PD_ROLE_UFP, 2,
+ 0, PD_REV30, 0);
+ rx_emsg[PORT0].len = 0;
+ fake_prl_message_received(PORT0);
+ task_wait_event(200 * MSEC);
+
+ /*
+ * Now connected. Send GET_SOURCE_CAP, to check how error sending
+ * SOURCE_CAP is handled.
+ */
+ rx_emsg[PORT0].header = PD_HEADER(PD_CTRL_GET_SOURCE_CAP, PD_ROLE_SINK,
+ PD_ROLE_UFP, 3,
+ 0, PD_REV30, 0);
+ rx_emsg[PORT0].len = 0;
+ fake_prl_message_received(PORT0);
+ task_wait_event(10 * MSEC);
+ TEST_EQ(fake_prl_get_last_sent_data_msg_type(PORT0),
+ PD_DATA_SOURCE_CAP, "%d");
+
+ /* Simulate error sending SOURCE_CAP. */
+ fake_prl_report_error(PORT0, ERR_TCH_XMIT);
+ task_wait_event(20 * MSEC);
+
+ /*
+ * Expect SOFT_RESET.
+ * See section 8.3.3.4.1.1 PE_SRC_Send_Soft_Reset State and section
+ * 8.3.3.2.3 PE_SRC_Send_Capabilities State.
+ * "The PE_SRC_Send_Soft_Reset state Shall be entered from any state
+ * when ... A Message has not been sent after retries to the Sink"
+ */
+ TEST_EQ(fake_prl_get_last_sent_ctrl_msg(PORT0),
+ PD_CTRL_SOFT_RESET, "%d");
+ fake_prl_message_sent(PORT0);
+ task_wait_event(5 * SECOND);
+
+ return EC_SUCCESS;
}
void run_test(int argc, char **argv)
{
test_reset();
+ RUN_TEST(test_send_caps_error);
+
/* Do basic state machine validity checks last. */
RUN_TEST(test_pe_no_parent_cycles);
diff --git a/test/usb_prl.c b/test/usb_prl.c
index fa5444c85c..d0f3d48322 100644
--- a/test/usb_prl.c
+++ b/test/usb_prl.c
@@ -5,23 +5,24 @@
* Test USB Protocol Layer module.
*/
#include "common.h"
+#include "mock/tcpc_mock.h"
+#include "mock/tcpm_mock.h"
+#include "mock/usb_pd_mock.h"
+#include "mock/usb_pe_sm_mock.h"
+#include "mock/usb_tc_sm_mock.h"
#include "task.h"
#include "tcpci.h"
#include "tcpm.h"
#include "test_util.h"
#include "timer.h"
#include "usb_emsg.h"
-#include "usb_pd_test_util.h"
#include "usb_pd.h"
+#include "usb_pd_test_util.h"
#include "usb_pe_sm.h"
#include "usb_prl_sm.h"
#include "usb_sm_checks.h"
#include "usb_tc_sm.h"
#include "util.h"
-#include "mock/tcpc_mock.h"
-#include "mock/tcpm_mock.h"
-#include "mock/usb_tc_sm_mock.h"
-#include "mock/usb_pe_sm_mock.h"
#define PORT0 0
@@ -47,8 +48,8 @@ static int test_receive_control_msg(void)
{
int port = PORT0;
uint16_t header = PD_HEADER(PD_CTRL_DR_SWAP,
- mock_tc_port[port].power_role,
- mock_tc_port[port].data_role,
+ pd_get_power_role(port),
+ pd_get_data_role(port),
mock_tc_port[port].msg_rx_id,
0, mock_tc_port[port].rev, 0);
@@ -99,8 +100,8 @@ static int test_discard_queued_tx_when_rx_happens(void)
{
int port = PORT0;
uint16_t header = PD_HEADER(PD_CTRL_DR_SWAP,
- mock_tc_port[port].power_role,
- mock_tc_port[port].data_role,
+ pd_get_power_role(port),
+ pd_get_data_role(port),
mock_tc_port[port].msg_rx_id,
0, mock_tc_port[port].rev, 0);
uint8_t *buf = tx_emsg[port].buf;
@@ -139,8 +140,8 @@ void before_test(void)
{
mock_tc_port_reset();
mock_tc_port[PORT0].rev = PD_REV30;
- mock_tc_port[PORT0].power_role = PD_ROLE_SOURCE;
- mock_tc_port[PORT0].data_role = PD_ROLE_DFP;
+ mock_pd_port[PORT0].power_role = PD_ROLE_SOURCE;
+ mock_pd_port[PORT0].data_role = PD_ROLE_DFP;
mock_tcpm_reset();
mock_pe_port_reset();