summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Brockus <dbrockus@google.com>2020-12-29 12:57:03 -0700
committerCommit Bot <commit-bot@chromium.org>2020-12-30 22:34:04 +0000
commit1ea0a8ad86d4d731a2fbb1861038564b393fbc82 (patch)
treece00adc912a0b34a65c7bf70ca4113608b71f349
parentc7641168a60cae345bddc5566bd7bf7aedd4d1ed (diff)
downloadchrome-ec-1ea0a8ad86d4d731a2fbb1861038564b393fbc82.tar.gz
TCPMv2: Compliance Unit Test - TD.PD.SRC.E2
BUG=none BRANCH=none TEST=make buildall Signed-off-by: Denis Brockus <dbrockus@google.com> Change-Id: I0b498d56dd189e3360fd1498acbfb5314c9870d0 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2602844 Tested-by: Denis Brockus <dbrockus@chromium.org> Reviewed-by: Keith Short <keithshort@chromium.org> Commit-Queue: Keith Short <keithshort@chromium.org> Auto-Submit: Denis Brockus <dbrockus@chromium.org>
-rw-r--r--common/mock/tcpci_i2c_mock.c23
-rw-r--r--include/mock/tcpci_i2c_mock.h6
-rw-r--r--test/build.mk1
-rw-r--r--test/usb_tcpmv2_compliance.c1
-rw-r--r--test/usb_tcpmv2_compliance.h1
-rw-r--r--test/usb_tcpmv2_td_pd_src_e2.c157
6 files changed, 189 insertions, 0 deletions
diff --git a/common/mock/tcpci_i2c_mock.c b/common/mock/tcpci_i2c_mock.c
index 8dcc84e034..ce07241577 100644
--- a/common/mock/tcpci_i2c_mock.c
+++ b/common/mock/tcpci_i2c_mock.c
@@ -70,6 +70,7 @@ static struct tcpci_reg tcpci_regs[] = {
static uint8_t tx_buffer[BUFFER_SIZE];
static int tx_pos = -1;
+static int tx_msg_cnt;
static int tx_retry_cnt = -1;
static uint8_t rx_buffer[BUFFER_SIZE];
static int rx_pos = -1;
@@ -231,6 +232,26 @@ int verify_tcpci_tx_retry_count(enum tcpm_transmit_type tx_type,
VERIFY_TIMEOUT);
}
+int verify_tcpci_tx_with_data(enum tcpm_transmit_type tx_type,
+ enum pd_data_msg_type data_msg,
+ uint8_t *data,
+ int data_bytes,
+ int *msg_len)
+{
+ int rv;
+
+ rv = verify_transmit(tx_type, -1,
+ 0, data_msg,
+ VERIFY_TIMEOUT);
+ if (!rv) {
+ TEST_NE(data, NULL, "%p");
+ TEST_GE(data_bytes, tx_msg_cnt, "%d");
+ memcpy(data, tx_buffer, tx_msg_cnt);
+ if (msg_len)
+ *msg_len = tx_msg_cnt;
+ }
+ return rv;
+}
void mock_tcpci_receive(enum pd_msg_type sop, uint16_t header,
uint32_t *payload)
{
@@ -431,6 +452,7 @@ int tcpci_i2c_xfer(int port, uint16_t slave_addr_flags,
}
memcpy(tx_buffer + tx_pos, out, out_size);
tx_pos += out_size;
+ tx_msg_cnt = tx_pos;
if (tx_pos > 0 && tx_pos == tx_buffer[0] + 1) {
print_header("TX", UINT16_FROM_BYTE_ARRAY_LE(
tx_buffer, 1));
@@ -450,6 +472,7 @@ int tcpci_i2c_xfer(int port, uint16_t slave_addr_flags,
return EC_ERROR_UNKNOWN;
}
tx_pos = 0;
+ tx_msg_cnt = 0;
if (out_size != 1) {
ccprints("ERROR: TCPC_REG_TX_BUFFER out_size != 1");
return EC_ERROR_UNKNOWN;
diff --git a/include/mock/tcpci_i2c_mock.h b/include/mock/tcpci_i2c_mock.h
index 7b068280d4..2c7faabd37 100644
--- a/include/mock/tcpci_i2c_mock.h
+++ b/include/mock/tcpci_i2c_mock.h
@@ -30,6 +30,12 @@ int verify_tcpci_tx_timeout(enum tcpm_transmit_type tx_type,
enum pd_data_msg_type data_msg,
int timeout);
+int verify_tcpci_tx_with_data(enum tcpm_transmit_type tx_type,
+ enum pd_data_msg_type data_msg,
+ uint8_t *data,
+ int data_bytes,
+ int *msg_len);
+
void mock_tcpci_receive(enum pd_msg_type sop, uint16_t header,
uint32_t *payload);
diff --git a/test/build.mk b/test/build.mk
index d0f813adb2..526eca8f22 100644
--- a/test/build.mk
+++ b/test/build.mk
@@ -221,6 +221,7 @@ usb_tcpmv2_compliance-y=usb_tcpmv2_compliance.o usb_tcpmv2_compliance_common.o \
usb_tcpmv2_td_pd_ll_e4.o \
usb_tcpmv2_td_pd_ll_e5.o \
usb_tcpmv2_td_pd_src_e1.o \
+ usb_tcpmv2_td_pd_src_e2.o \
usb_tcpmv2_td_pd_src3_e26.o \
usb_tcpmv2_td_pd_snk3_e12.o \
usb_tcpmv2_td_pd_other.o
diff --git a/test/usb_tcpmv2_compliance.c b/test/usb_tcpmv2_compliance.c
index f2e8924638..aab01cf534 100644
--- a/test/usb_tcpmv2_compliance.c
+++ b/test/usb_tcpmv2_compliance.c
@@ -34,6 +34,7 @@ void run_test(int argc, char **argv)
RUN_TEST(test_td_pd_ll_e5_dfp);
RUN_TEST(test_td_pd_ll_e5_ufp);
RUN_TEST(test_td_pd_src_e1);
+ RUN_TEST(test_td_pd_src_e2);
RUN_TEST(test_td_pd_src3_e26);
RUN_TEST(test_td_pd_snk3_e12);
diff --git a/test/usb_tcpmv2_compliance.h b/test/usb_tcpmv2_compliance.h
index 4b57ebb11d..654ca0c421 100644
--- a/test/usb_tcpmv2_compliance.h
+++ b/test/usb_tcpmv2_compliance.h
@@ -80,6 +80,7 @@ int test_td_pd_ll_e5_dfp(void);
int test_td_pd_ll_e5_ufp(void);
int test_td_pd_src_e1(void);
+int test_td_pd_src_e2(void);
int test_td_pd_src3_e26(void);
diff --git a/test/usb_tcpmv2_td_pd_src_e2.c b/test/usb_tcpmv2_td_pd_src_e2.c
new file mode 100644
index 0000000000..7943c0fa86
--- /dev/null
+++ b/test/usb_tcpmv2_td_pd_src_e2.c
@@ -0,0 +1,157 @@
+/* Copyright 2020 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "mock/tcpci_i2c_mock.h"
+#include "task.h"
+#include "tcpci.h"
+#include "test_util.h"
+#include "timer.h"
+#include "usb_tcpmv2_compliance.h"
+#include "usb_tc_sm.h"
+
+#define BUFFER_SIZE 100
+#define HEADER_BYTE_CNT 2
+#define PDO_BYTE_CNT 4
+
+enum pd_revision {
+ REVISION_1 = 0,
+ REVISION_2 = 1,
+ REVISION_3 = 2,
+ REVISION_RESERVED = 3
+};
+
+/*****************************************************************************
+ * TD.PD.SRC.E2 Source Capabilities Fields Checks
+ *
+ * Description:
+ * As Consumer (UFP), the Tester waits for a Source Capabilities message
+ * from the Provider (DFP,UUT) and verifies correct field values.
+ */
+int test_td_pd_src_e2(void)
+{
+ int i;
+ int msg_len;
+ uint8_t data[BUFFER_SIZE];
+ uint16_t header;
+ uint16_t revision;
+ uint16_t pd_cnt;
+ uint32_t pdo;
+ uint32_t type;
+ uint32_t last_fixed_voltage = 0;
+ uint32_t last_battery_voltage = 0;
+ uint32_t last_variable_voltage = 0;
+
+ partner_set_pd_rev(PD_REV20);
+
+ TEST_EQ(tcpci_startup(), EC_SUCCESS, "%d");
+
+ /*
+ * a) Run PROC.PD.E1 Bring-up according to the UUT role.
+ *
+ * NOTE: Calling PROC.PD.E1 with INITIAL_ATTACH will stop just before
+ * the PD_DATA_SOURCE_CAP is verified. We need to stop the process
+ * there to gather the actual message data.
+ */
+ TEST_EQ(proc_pd_e1(PD_ROLE_DFP, INITIAL_ATTACH), EC_SUCCESS, "%d");
+
+ /*
+ * b) Upon receipt of the Source Capabilities message from the
+ * Provider, if the Specification Revision field is 10b
+ * (Rev 3.0), the test passes and stops here,
+ */
+ TEST_EQ(verify_tcpci_tx_with_data(TCPC_TX_SOP,
+ PD_DATA_SOURCE_CAP,
+ data,
+ sizeof(data),
+ &msg_len),
+ EC_SUCCESS, "%d");
+ TEST_GE(msg_len, HEADER_BYTE_CNT, "%d");
+
+ header = UINT16_FROM_BYTE_ARRAY_LE(data, 1);
+ revision = PD_HEADER_REV(header);
+ if (revision == REVISION_3)
+ return EC_SUCCESS;
+
+ /*
+ * otherwise the Tester verifies:
+ * 1. Number of Data Objects field equals the number of Src_PDOs
+ * in the message and is not 000b.
+ * 2. Port Power Role field = 1b (Source)
+ * 3. Specification Revision field = 01b (Rev 2.0)
+ * 4. Port Data Role field = 1b (DFP)
+ * 5. Message Type field = 0001b (Source Capabilities)
+ * 6. Bit 15 = 0b (Reserved)
+ * 7. Bit 4 = 0b (Reserved)
+ */
+ pd_cnt = PD_HEADER_CNT(header);
+ TEST_NE(pd_cnt, 0, "%d");
+ TEST_EQ(msg_len, HEADER_BYTE_CNT + (pd_cnt * PDO_BYTE_CNT) + 1, "%d");
+ TEST_EQ(PD_HEADER_PROLE(header), PD_ROLE_SOURCE, "%d");
+ TEST_EQ(revision, REVISION_2, "%d");
+ TEST_EQ(PD_HEADER_DROLE(header), PD_ROLE_DFP, "%d");
+ TEST_EQ(PD_HEADER_TYPE(header), PD_DATA_SOURCE_CAP, "%d");
+ TEST_EQ(header & (BIT(4)|BIT(15)), 0, "%d");
+
+ /*
+ * c) For the first PDO, the Tester verifies:
+ * 1. Bits 31..30 (PDO type) are 00b (Fixed Supply).
+ * 2. Voltage field = 100 (5 V)
+ * 3. Bits 24..22 = 000b (Reserved)
+ */
+ pdo = UINT32_FROM_BYTE_ARRAY_LE(&data[2], 1);
+
+ type = pdo & PDO_TYPE_MASK;
+ TEST_EQ(type, PDO_TYPE_FIXED, "%d");
+
+ last_fixed_voltage = PDO_FIXED_VOLTAGE(pdo);
+ TEST_EQ(last_fixed_voltage, 5000, "%d");
+ TEST_EQ(pdo & GENMASK(24, 22), 0, "%d");
+
+ /*
+ * d) For the other PDOs (if any), the Tester verifies:
+ * 1. Bits 31..30 (PDO type) are 00b (Fixed Supply), 01b (Battery),
+ * or 10b (Variable Supply).
+ * 2. If Bits 31..30 are 00b, Bits 29..22 are set to 0.
+ * 3. PDOs are in the order of Fixed Supply Objects (if present),
+ * Battery Supply Objects (if present) and then Variable Supply
+ * Objects (if present).
+ * 4. Fixed Supply Objects (if present) are in voltage order; lowest
+ * to highest.
+ * 5. Battery Supply Objects (if present) are in Minimum Voltage
+ * order; lowest to highest.
+ * 6. Variable Supply Objects (if present) are in Minimum Voltage
+ * order; lowest to highest.
+ */
+ for (i = 1; i < pd_cnt; ++i) {
+ int offset;
+ uint32_t voltage;
+
+ offset = HEADER_BYTE_CNT + (i * PDO_BYTE_CNT);
+ pdo = UINT32_FROM_BYTE_ARRAY_LE(&data[offset], 1);
+
+ type = pdo & PDO_TYPE_MASK;
+ TEST_NE(type, PDO_TYPE_AUGMENTED, "%d");
+
+ if (type == PDO_TYPE_FIXED) {
+ TEST_EQ(pdo & GENMASK(29, 22), 0, "%d");
+ TEST_EQ(last_battery_voltage, 0, "%d");
+ TEST_EQ(last_variable_voltage, 0, "%d");
+ voltage = PDO_FIXED_VOLTAGE(pdo);
+ TEST_GE(voltage, last_fixed_voltage, "%d");
+ last_fixed_voltage = voltage;
+ } else if (type == PDO_TYPE_BATTERY) {
+ TEST_EQ(last_variable_voltage, 0, "%d");
+ voltage = PDO_BATT_MIN_VOLTAGE(pdo);
+ TEST_GE(voltage, last_battery_voltage, "%d");
+ last_battery_voltage = voltage;
+ } else {
+ voltage = PDO_VAR_MIN_VOLTAGE(pdo);
+ TEST_GE(voltage, last_variable_voltage, "%d");
+ last_variable_voltage = voltage;
+ }
+ }
+
+ return EC_SUCCESS;
+}