summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJett Rink <jettrink@chromium.org>2020-06-16 16:20:17 -0600
committerCommit Bot <commit-bot@chromium.org>2020-08-06 02:06:20 +0000
commitd94d4cc45e39297cd4e072a07c8fca714715fa18 (patch)
tree19873d2936d701b02c7f778ab99166115d42a08a
parent17fed25d34ec92fa0c7c3bfc738e4ca63c20bba4 (diff)
downloadchrome-ec-d94d4cc45e39297cd4e072a07c8fca714715fa18.tar.gz
tcpmc2: fix TD.PD.LL3.E2 Retransmission test
We are retrying in both the TCPC hardware (4 total) and in the Protocol layer (3 total) when we do not get a GoodCRC back from the port partner. We are only suppose to retry up to nRetryCount times which is 2. This means we should be sending 3 total replies. Also correct a misinterpretation of the spec around SOP' and SOP" retries. We were not retrying those packets, but we should be retry them as the SOP. The SOP' device will not retry, but we (as the SOP) should retry packet that we are sending to them. The TCPM is not fast enough to meet the timing for tRetry (195 usec), so we need to perform the retries in the TCPC hardware layer. BRANCH=none BUG=b:150617035 TEST=Verify passing compliance test with GRL-C2 on Trembyle Change-Id: I55c4ab2f5ce8f64acf21af943862d96d9088622d Signed-off-by: Jett Rink <jettrink@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2248960
-rw-r--r--board/servo_v4p1/fusb302b.h3
-rw-r--r--common/mock/tcpci_i2c_mock.c40
-rw-r--r--common/usb_pd_protocol.c3
-rw-r--r--common/usb_pd_tcpc.c3
-rw-r--r--common/usbc/usb_prl_sm.c100
-rw-r--r--driver/tcpm/fusb302.c3
-rw-r--r--driver/tcpm/fusb302.h3
-rw-r--r--driver/tcpm/it83xx.c4
-rw-r--r--driver/tcpm/it8xxx2.c4
-rw-r--r--driver/tcpm/tcpci.c14
-rw-r--r--driver/tcpm/tcpci.h2
-rw-r--r--include/config.h16
-rw-r--r--include/mock/tcpci_i2c_mock.h8
-rw-r--r--include/usb_pd_tcpm.h3
-rw-r--r--include/usb_prl_sm.h5
-rw-r--r--test/usb_prl_old.c133
-rw-r--r--test/usb_tcpmv2_tcpci.c94
17 files changed, 187 insertions, 251 deletions
diff --git a/board/servo_v4p1/fusb302b.h b/board/servo_v4p1/fusb302b.h
index 2f0cd207b8..eddc97b7ca 100644
--- a/board/servo_v4p1/fusb302b.h
+++ b/board/servo_v4p1/fusb302b.h
@@ -22,9 +22,6 @@
/* FUSB302B11MPX */
#define FUSB302_I2C_SLAVE_ADDR_B11_FLAGS 0x25
-/* Default retry count for transmitting */
-#define PD_RETRY_COUNT 3
-
#define TCPC_REG_DEVICE_ID 0x01
#define TCPC_REG_SWITCHES0 0x02
diff --git a/common/mock/tcpci_i2c_mock.c b/common/mock/tcpci_i2c_mock.c
index a0aa40dba4..09864cc2d2 100644
--- a/common/mock/tcpci_i2c_mock.c
+++ b/common/mock/tcpci_i2c_mock.c
@@ -10,6 +10,7 @@
#include "timer.h"
#define BUFFER_SIZE 100
+#define MOCK_WAIT_TIMEOUT (5 * SECOND)
struct tcpci_reg {
uint8_t offset;
@@ -137,14 +138,11 @@ static void print_header(const char *prefix, uint16_t header)
id, cnt, ext);
}
-int mock_tcpci_wait_for_transmit(enum tcpm_transmit_type tx_type,
+int verify_tcpci_transmit(enum tcpm_transmit_type tx_type,
enum pd_ctrl_msg_type ctrl_msg,
enum pd_data_msg_type data_msg)
{
- int want_tx_reg = (tx_type == TCPC_TX_SOP_PRIME) ?
- TCPC_REG_TRANSMIT_SET_WITHOUT_RETRY(tx_type) :
- TCPC_REG_TRANSMIT_SET_WITH_RETRY(tx_type);
- uint64_t timeout = get_time().val + 5 * SECOND;
+ uint64_t timeout = get_time().val + MOCK_WAIT_TIMEOUT;
TEST_EQ(tcpci_regs[TCPC_REG_TRANSMIT].value, 0, "%d");
while (get_time().val < timeout) {
@@ -153,14 +151,17 @@ int mock_tcpci_wait_for_transmit(enum tcpm_transmit_type tx_type,
tx_buffer, 1);
int type = PD_HEADER_TYPE(header);
int cnt = PD_HEADER_CNT(header);
+ const uint16_t want_tx_reg = tx_type;
+ const uint16_t tx_wo_retry =
+ tcpci_regs[TCPC_REG_TRANSMIT].value & ~0x0030;
- TEST_EQ(tcpci_regs[TCPC_REG_TRANSMIT].value,
- want_tx_reg, "%d");
+ /* Don't validate the retry portion of reg */
+ TEST_EQ(tx_wo_retry, want_tx_reg, "0x%x");
if (ctrl_msg != 0) {
- TEST_EQ(ctrl_msg, type, "%d");
+ TEST_EQ(ctrl_msg, type, "0x%x");
TEST_EQ(cnt, 0, "%d");
} else {
- TEST_EQ(data_msg, type, "%d");
+ TEST_EQ(data_msg, type, "0x%x");
TEST_GE(cnt, 1, "%d");
}
tcpci_regs[TCPC_REG_TRANSMIT].value = 0;
@@ -172,6 +173,27 @@ int mock_tcpci_wait_for_transmit(enum tcpm_transmit_type tx_type,
return EC_ERROR_UNKNOWN;
}
+int verify_tcpci_tx_retry_count(const uint8_t retry_count)
+{
+ uint64_t timeout = get_time().val + MOCK_WAIT_TIMEOUT;
+
+ TEST_EQ(tcpci_regs[TCPC_REG_TRANSMIT].value, 0, "%d");
+ while (get_time().val < timeout) {
+ if (tcpci_regs[TCPC_REG_TRANSMIT].value != 0) {
+ const uint16_t tx_retry = TCPC_REG_TRANSMIT_RETRY(
+ tcpci_regs[TCPC_REG_TRANSMIT].value);
+
+ TEST_EQ(tx_retry, retry_count, "%d");
+
+ tcpci_regs[TCPC_REG_TRANSMIT].value = 0;
+ return EC_SUCCESS;
+ }
+ task_wait_event(5 * MSEC);
+ }
+ TEST_ASSERT(0);
+ return EC_ERROR_UNKNOWN;
+}
+
void mock_tcpci_receive(enum pd_msg_type sop, uint16_t header,
uint32_t *payload)
{
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index ececdde8ed..06ef2b630a 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -5046,7 +5046,8 @@ void pd_send_hpd(int port, enum hpd_event hpd)
VDO_OPOS(opos) | CMD_ATTENTION, data, 1);
/* Wait until VDM is done. */
while (pd[0].vdm_state > 0)
- task_wait_event(USB_PD_RX_TMOUT_US * (PD_RETRY_COUNT + 1));
+ task_wait_event(USB_PD_RX_TMOUT_US *
+ (CONFIG_PD_RETRY_COUNT + 1));
}
#endif
diff --git a/common/usb_pd_tcpc.c b/common/usb_pd_tcpc.c
index 5100319115..2878e53574 100644
--- a/common/usb_pd_tcpc.c
+++ b/common/usb_pd_tcpc.c
@@ -387,7 +387,8 @@ static int send_validate_message(int port, uint16_t header,
uint8_t expected_msg_id = PD_HEADER_ID(header);
uint8_t cnt = PD_HEADER_CNT(header);
int retries = PD_HEADER_TYPE(header) == PD_DATA_SOURCE_CAP ?
- 0 : PD_RETRY_COUNT;
+ 0 :
+ CONFIG_PD_RETRY_COUNT;
/* retry 3 times if we are not getting a valid answer */
for (r = 0; r <= retries; r++) {
diff --git a/common/usbc/usb_prl_sm.c b/common/usbc/usb_prl_sm.c
index ce32e0caf0..ec22502523 100644
--- a/common/usbc/usb_prl_sm.c
+++ b/common/usbc/usb_prl_sm.c
@@ -253,14 +253,12 @@ static struct protocol_layer_tx {
uint32_t flags;
/* protocol timer */
uint64_t sink_tx_timer;
- /* tcpc transmit timeout */
+ /* timeout to limit waiting on TCPC response (not in spec) */
uint64_t tcpc_tx_timeout;
/* last message type we transmitted */
enum tcpm_transmit_type last_xmit_type;
/* message id counters for all 6 port partners */
uint32_t msg_id_counter[NUM_SOP_STAR_TYPES];
- /* message retry counter */
- uint32_t retry_counter;
/* transmit status */
int xmit_status;
} prl_tx[CONFIG_USB_PD_PORT_MAX_COUNT];
@@ -768,9 +766,6 @@ static void prl_tx_phy_layer_reset_entry(const int port)
static void prl_tx_wait_for_message_request_entry(const int port)
{
print_current_prl_tx_state(port);
-
- /* Reset RetryCounter */
- prl_tx[port].retry_counter = 0;
}
static void prl_tx_wait_for_message_request_run(const int port)
@@ -980,9 +975,16 @@ static void prl_tx_construct_message(const int port)
prl_tx[port].xmit_status = TCPC_TX_UNSET;
PDMSG_CLR_FLAG(port, PRL_FLAGS_TX_COMPLETE);
- /* Pass message to PHY Layer */
+ /*
+ * Pass message to PHY Layer. It handles retries in hardware as the EC
+ * cannot handle the required timing ~ 1ms (tReceive + tRetry).
+ *
+ * Note if we ever start sending large, extendend messages, then we
+ * should not retry those messages. We do not support that and probably
+ * never will (since we support chunking).
+ */
tcpm_transmit(port, pdmsg[port].xmit_type, header,
- pdmsg[port].tx_chk_buf);
+ pdmsg[port].tx_chk_buf);
}
/*
@@ -997,71 +999,16 @@ static void prl_tx_wait_for_phy_response_entry(const int port)
static void prl_tx_wait_for_phy_response_run(const int port)
{
- int pd3_retry_check;
-
/* Wait until TX is complete */
/*
* NOTE: The TCPC will set xmit_status to TCPC_TX_COMPLETE_DISCARDED
* when a GoodCRC containing an incorrect MessageID is received.
- * This condition satifies the PRL_Tx_Match_MessageID state
+ * This condition satisfies the PRL_Tx_Match_MessageID state
* requirement.
*/
- if (get_time().val > prl_tx[port].tcpc_tx_timeout ||
- prl_tx[port].xmit_status == TCPC_TX_COMPLETE_FAILED ||
- prl_tx[port].xmit_status == TCPC_TX_COMPLETE_DISCARDED) {
-
- /* NOTE: PRL_Tx_Check_RetryCounter State embedded here. */
-
- /* Increment check RetryCounter */
- prl_tx[port].retry_counter++;
-
-#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES
- pd3_retry_check = (pdmsg[port].ext &&
- PD_EXT_HEADER_DATA_SIZE(GET_EXT_HEADER(
- pdmsg[port].tx_chk_buf[0]) >
- PD_MAX_EXTENDED_MSG_CHUNK_LEN));
-#else
- pd3_retry_check = 0;
-#endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */
-
- /*
- * (RetryCounter > nRetryCount) | Large Extended Message
- */
- if (prl_tx[port].retry_counter > N_RETRY_COUNT ||
- pd3_retry_check) {
- /*
- * NOTE: PRL_Tx_Transmission_Error State embedded
- * here.
- */
-
- if (IS_ENABLED(CONFIG_USB_PD_EXTENDED_MESSAGES)) {
- /*
- * State tch_wait_for_transmission_complete will
- * inform policy engine of error
- */
- PDMSG_SET_FLAG(port, PRL_FLAGS_TX_ERROR);
- } else {
- /* Report Error To Policy Engine */
- pe_report_error(port, ERR_TCH_XMIT,
- prl_tx[port].last_xmit_type);
- }
-
- /* Increment message id counter */
- increment_msgid_counter(port);
- set_state_prl_tx(port, PRL_TX_WAIT_FOR_MESSAGE_REQUEST);
- } else {
- /*
- * NOTE: PRL_TX_Construct_Message State embedded
- * here.
- */
- /* Try to resend the message. */
- prl_tx_construct_message(port);
- prl_tx[port].tcpc_tx_timeout = get_time().val
- + PD_T_TCPC_TX_TIMEOUT;
- }
- } else if (prl_tx[port].xmit_status == TCPC_TX_COMPLETE_SUCCESS) {
+ if (prl_tx[port].xmit_status == TCPC_TX_COMPLETE_SUCCESS) {
/* NOTE: PRL_TX_Message_Sent State embedded here. */
/* Increment messageId counter */
increment_msgid_counter(port);
@@ -1078,6 +1025,29 @@ static void prl_tx_wait_for_phy_response_run(const int port)
*/
task_set_event(PD_PORT_TO_TASK_ID(port), PD_EVENT_SM, 0);
set_state_prl_tx(port, PRL_TX_WAIT_FOR_MESSAGE_REQUEST);
+ } else if (get_time().val > prl_tx[port].tcpc_tx_timeout ||
+ prl_tx[port].xmit_status == TCPC_TX_COMPLETE_FAILED ||
+ prl_tx[port].xmit_status == TCPC_TX_COMPLETE_DISCARDED) {
+ /*
+ * NOTE: PRL_Tx_Transmission_Error State embedded
+ * here.
+ */
+
+ if (IS_ENABLED(CONFIG_USB_PD_EXTENDED_MESSAGES)) {
+ /*
+ * State tch_wait_for_transmission_complete will
+ * inform policy engine of error
+ */
+ PDMSG_SET_FLAG(port, PRL_FLAGS_TX_ERROR);
+ } else {
+ /* Report Error To Policy Engine */
+ pe_report_error(port, ERR_TCH_XMIT,
+ prl_tx[port].last_xmit_type);
+ }
+
+ /* Increment message id counter */
+ increment_msgid_counter(port);
+ set_state_prl_tx(port, PRL_TX_WAIT_FOR_MESSAGE_REQUEST);
}
}
diff --git a/driver/tcpm/fusb302.c b/driver/tcpm/fusb302.c
index 74d32a2052..5ec8c284c2 100644
--- a/driver/tcpm/fusb302.c
+++ b/driver/tcpm/fusb302.c
@@ -403,8 +403,7 @@ static int fusb302_tcpm_init(int port)
/* Turn on retries and set number of retries */
tcpc_read(port, TCPC_REG_CONTROL3, &reg);
reg |= TCPC_REG_CONTROL3_AUTO_RETRY;
- reg |= (PD_RETRY_COUNT & 0x3) <<
- TCPC_REG_CONTROL3_N_RETRIES_POS;
+ reg |= (CONFIG_PD_RETRY_COUNT & 0x3) << TCPC_REG_CONTROL3_N_RETRIES_POS;
tcpc_write(port, TCPC_REG_CONTROL3, reg);
/* Create interrupt masks */
diff --git a/driver/tcpm/fusb302.h b/driver/tcpm/fusb302.h
index fee246aeb2..8db9f86c20 100644
--- a/driver/tcpm/fusb302.h
+++ b/driver/tcpm/fusb302.h
@@ -24,9 +24,6 @@
/* FUSB302B11MPX */
#define FUSB302_I2C_SLAVE_ADDR_B11_FLAGS 0x25
-/* Default retry count for transmitting */
-#define PD_RETRY_COUNT 3
-
#define TCPC_REG_DEVICE_ID 0x01
#define TCPC_REG_SWITCHES0 0x02
diff --git a/driver/tcpm/it83xx.c b/driver/tcpm/it83xx.c
index 4a53f14a2f..f69c631ff2 100644
--- a/driver/tcpm/it83xx.c
+++ b/driver/tcpm/it83xx.c
@@ -195,7 +195,7 @@ static enum tcpc_transmit_complete it83xx_tx_data(
memcpy((uint32_t *)&IT83XX_USBPD_TDO(port), buf, length * 4);
}
- for (r = 0; r <= PD_RETRY_COUNT; r++) {
+ for (r = 0; r <= CONFIG_PD_RETRY_COUNT; r++) {
/* Start TX */
USBPD_KICK_TX_START(port);
evt = task_wait_event_mask(TASK_EVENT_PHY_TX_DONE,
@@ -217,7 +217,7 @@ static enum tcpc_transmit_complete it83xx_tx_data(
}
}
- if (r > PD_RETRY_COUNT)
+ if (r > CONFIG_PD_RETRY_COUNT)
return TCPC_TX_COMPLETE_DISCARDED;
return TCPC_TX_COMPLETE_SUCCESS;
diff --git a/driver/tcpm/it8xxx2.c b/driver/tcpm/it8xxx2.c
index af04871017..33b102ba7b 100644
--- a/driver/tcpm/it8xxx2.c
+++ b/driver/tcpm/it8xxx2.c
@@ -187,7 +187,7 @@ static enum tcpc_transmit_complete it83xx_tx_data(
/* Set data */
memcpy((uint32_t *)&IT83XX_USBPD_TDO(port), buf, length * 4);
- for (r = 0; r <= PD_RETRY_COUNT; r++) {
+ for (r = 0; r <= CONFIG_PD_RETRY_COUNT; r++) {
/* Start Tx */
USBPD_KICK_TX_START(port);
evt = task_wait_event_mask(TASK_EVENT_PHY_TX_DONE,
@@ -230,7 +230,7 @@ static enum tcpc_transmit_complete it83xx_tx_data(
break;
}
- if (r > PD_RETRY_COUNT)
+ if (r > CONFIG_PD_RETRY_COUNT)
return TCPC_TX_COMPLETE_DISCARDED;
return TCPC_TX_COMPLETE_SUCCESS;
diff --git a/driver/tcpm/tcpci.c b/driver/tcpm/tcpci.c
index 80f2a134f1..008f3bd589 100644
--- a/driver/tcpm/tcpci.c
+++ b/driver/tcpm/tcpci.c
@@ -968,17 +968,15 @@ int tcpci_tcpm_transmit(int port, enum tcpm_transmit_type type,
}
}
-
/*
- * On receiving a received message on SOP, protocol layer
- * discards the pending SOP messages queued for transmission.
- * But it doesn't do the same for SOP' message. So retry is
- * assigned to 0 to avoid multiple transmission.
+ * We always retry in TCPC hardware since the TCPM is too slow to
+ * respond within tRetry (~195 usec).
+ *
+ * The retry count used is dependent on the maximum PD revision
+ * supported at build time.
*/
return tcpc_write(port, TCPC_REG_TRANSMIT,
- (type == TCPC_TX_SOP_PRIME) ?
- TCPC_REG_TRANSMIT_SET_WITHOUT_RETRY(type) :
- TCPC_REG_TRANSMIT_SET_WITH_RETRY(type));
+ TCPC_REG_TRANSMIT_SET_WITH_RETRY(type));
}
/*
diff --git a/driver/tcpm/tcpci.h b/driver/tcpm/tcpci.h
index 7622d02e63..914b143c41 100644
--- a/driver/tcpm/tcpci.h
+++ b/driver/tcpm/tcpci.h
@@ -181,7 +181,7 @@
#define TCPC_REG_TRANSMIT 0x50
#define TCPC_REG_TRANSMIT_SET_WITH_RETRY(type) \
- (PD_RETRY_COUNT << 4 | (type))
+ (CONFIG_PD_RETRY_COUNT << 4 | (type))
#define TCPC_REG_TRANSMIT_SET_WITHOUT_RETRY(type) (type)
#define TCPC_REG_TRANSMIT_RETRY(reg) (((reg) & 0x30) >> 4)
#define TCPC_REG_TRANSMIT_TYPE(reg) ((reg) & 0x7)
diff --git a/include/config.h b/include/config.h
index 104b879234..a6032b9f14 100644
--- a/include/config.h
+++ b/include/config.h
@@ -3893,6 +3893,9 @@
*/
#undef CONFIG_USB_PD_REV30
+/* Defined automatically based on on maximum PD revision supported. */
+#undef CONFIG_PD_RETRY_COUNT
+
/*
* Support USB PD 3.0 Extended Messages. This will only take effect if
* CONFIG_USB_PD_REV30 is also enabled. Note that Chromebooks disabling this
@@ -4783,6 +4786,19 @@
/******************************************************************************/
/*
+ * PD 3.0 only retries in TCPC hardware twice (for a total of 3 attempts), while
+ * PD 2.0 retires three times (for a total of 4 attempts).
+ *
+ * Note must be [0-3] since it must fit within 2 bits.
+ */
+#ifdef CONFIG_USB_PD_REV30
+#define CONFIG_PD_RETRY_COUNT 2
+#else
+#define CONFIG_PD_RETRY_COUNT 3
+#endif
+
+/******************************************************************************/
+/*
* Ensure that CONFIG_USB_PD_TCPMV2 is being used with exactly one device type
*/
#ifdef CONFIG_USB_PD_TCPMV2
diff --git a/include/mock/tcpci_i2c_mock.h b/include/mock/tcpci_i2c_mock.h
index 06cb0ca5f4..4734a2e1e2 100644
--- a/include/mock/tcpci_i2c_mock.h
+++ b/include/mock/tcpci_i2c_mock.h
@@ -14,9 +14,11 @@ void mock_tcpci_set_reg(int reg, uint16_t value);
uint16_t mock_tcpci_get_reg(int reg_offset);
-int mock_tcpci_wait_for_transmit(enum tcpm_transmit_type tx_type,
- enum pd_ctrl_msg_type ctrl_msg,
- enum pd_data_msg_type data_msg);
+int verify_tcpci_transmit(enum tcpm_transmit_type tx_type,
+ enum pd_ctrl_msg_type ctrl_msg,
+ enum pd_data_msg_type data_msg);
+
+int verify_tcpci_tx_retry_count(uint8_t retry_count);
void mock_tcpci_receive(enum pd_msg_type sop, uint16_t header,
uint32_t *payload);
diff --git a/include/usb_pd_tcpm.h b/include/usb_pd_tcpm.h
index b039c6f63e..bccea184e4 100644
--- a/include/usb_pd_tcpm.h
+++ b/include/usb_pd_tcpm.h
@@ -12,9 +12,6 @@
#include "ec_commands.h"
#include "i2c.h"
-/* Default retry count for transmitting */
-#define PD_RETRY_COUNT 3
-
/* Time to wait for TCPC to complete transmit */
#define PD_T_TCPC_TX_TIMEOUT (100*MSEC)
diff --git a/include/usb_prl_sm.h b/include/usb_prl_sm.h
index 3575d9443b..4b99d4c4c3 100644
--- a/include/usb_prl_sm.h
+++ b/include/usb_prl_sm.h
@@ -12,11 +12,6 @@
#include "usb_pd_tcpm.h"
#include "usb_sm.h"
-/*
- * Number of times the Protocol Layer will try to transmit a message
- * before giving up and signaling an error
- */
-#define N_RETRY_COUNT 2
/**
* Returns true if Protocol Layer State Machine is in run mode
diff --git a/test/usb_prl_old.c b/test/usb_prl_old.c
index 22da3629d3..4c06c41b8b 100644
--- a/test/usb_prl_old.c
+++ b/test/usb_prl_old.c
@@ -859,135 +859,6 @@ static int test_send_ctrl_msg(void)
return EC_SUCCESS;
}
-static int test_send_ctrl_msg_with_retry_and_fail(void)
-{
- int i;
- int port = PORT0;
-
- enable_prl(port, 1);
-
- /*
- * TEST: Control message transmission fail with retry
- */
- task_wake(PD_PORT_TO_TASK_ID(port));
- task_wait_event(MSEC);
-
- TEST_EQ(prl_tx_get_state(port),
- PRL_TX_WAIT_FOR_MESSAGE_REQUEST, "%u");
-
- TEST_NE(simulate_send_ctrl_msg_request_from_pe(port,
- TCPC_TX_SOP, PD_CTRL_ACCEPT), 0, "%d");
-
- cycle_through_state_machine(port, 1, MSEC);
-
- simulate_goodcrc(port, pd_port[port].power_role,
- pd_port[port].msg_tx_id);
-
- /* Do not increment tx_id so phy layer will not transmit message */
-
- /* Let statemachine settle */
- cycle_through_state_machine(port, 10, MSEC);
-
- TEST_EQ(pd_port[port].mock_got_soft_reset, 0, "%d");
- TEST_NE(pd_port[port].mock_pe_message_sent, 0, "%d");
-
- task_wake(PD_PORT_TO_TASK_ID(port));
- task_wait_event(MSEC);
-
- TEST_EQ(prl_tx_get_state(port),
- PRL_TX_WAIT_FOR_MESSAGE_REQUEST, "%u");
-
- pd_port[port].mock_pe_message_sent = 0;
- prl_send_ctrl_msg(port, TCPC_TX_SOP, PD_CTRL_ACCEPT);
- cycle_through_state_machine(port, 1, MSEC);
-
- for (i = 0; i < N_RETRY_COUNT + 1; i++) {
- /* Ensure that we have timed out */
- cycle_through_state_machine(port, 12, MSEC);
-
- TEST_EQ(pd_port[port].mock_got_soft_reset, 0, "%d");
- TEST_EQ(pd_port[port].mock_pe_message_sent, 0, "%d");
- if (i == N_RETRY_COUNT)
- TEST_EQ(pd_port[port].mock_pe_error,
- ERR_TCH_XMIT, "%d");
- else
- TEST_LE(pd_port[port].mock_pe_error, 0, "%d");
- }
-
- enable_prl(port, 0);
-
- return EC_SUCCESS;
-}
-
-static int test_send_ctrl_msg_with_retry_and_success(void)
-{
- int i;
- int port = PORT0;
-
- enable_prl(port, 1);
-
- /*
- * TEST: Control message transmission fail with retry
- */
-
- TEST_EQ(prl_tx_get_state(port),
- PRL_TX_WAIT_FOR_MESSAGE_REQUEST, "%u");
-
- pd_port[port].mock_got_soft_reset = 0;
- pd_port[port].mock_pe_error = -1;
- pd_port[port].mock_pe_message_sent = 0;
-
- prl_send_ctrl_msg(port, TCPC_TX_SOP, PD_CTRL_ACCEPT);
- task_wait_event(40 * MSEC);
-
- task_wake(PD_PORT_TO_TASK_ID(port));
- task_wait_event(40 * MSEC);
-
- simulate_goodcrc(port, pd_port[port].power_role,
- pd_port[port].msg_tx_id);
-
- /* Do not increment tx_id. */
-
- cycle_through_state_machine(port, 3, 10 * MSEC);
-
- TEST_EQ(pd_port[port].mock_got_soft_reset, 0, "%d");
- TEST_NE(pd_port[port].mock_pe_message_sent, 0, "%d");
-
- task_wake(PD_PORT_TO_TASK_ID(port));
- task_wait_event(40 * MSEC);
-
- TEST_EQ(prl_tx_get_state(port),
- PRL_TX_WAIT_FOR_MESSAGE_REQUEST, "%u");
-
- pd_port[port].mock_pe_message_sent = 0;
- prl_send_ctrl_msg(port, TCPC_TX_SOP, PD_CTRL_ACCEPT);
- task_wait_event(30 * MSEC);
-
- task_wake(PD_PORT_TO_TASK_ID(port));
- task_wait_event(30 * MSEC);
-
- for (i = 0; i < N_RETRY_COUNT + 1; i++) {
- if (i == N_RETRY_COUNT)
- inc_tx_id(port);
-
- simulate_goodcrc(port, pd_port[port].power_role,
- pd_port[port].msg_tx_id);
-
- cycle_through_state_machine(port, 3, MSEC);
-
- TEST_EQ(pd_port[port].mock_got_soft_reset, 0, "%d");
- if (i == N_RETRY_COUNT)
- TEST_NE(pd_port[port].mock_pe_message_sent, 0, "%d");
- else
- TEST_EQ(pd_port[port].mock_pe_message_sent, 0, "%d");
- TEST_LE(pd_port[port].mock_pe_error, 0, "%d");
- }
-
- enable_prl(port, 0);
-
- return EC_SUCCESS;
-}
-
static int test_send_data_msg(void)
{
int i;
@@ -1415,8 +1286,6 @@ void run_test(int argc, char **argv)
init_port(PORT0, PD_REV20);
RUN_TEST(test_prl_reset);
RUN_TEST(test_send_ctrl_msg);
- RUN_TEST(test_send_ctrl_msg_with_retry_and_fail);
- RUN_TEST(test_send_ctrl_msg_with_retry_and_success);
RUN_TEST(test_send_data_msg);
RUN_TEST(test_send_data_msg_to_much_data);
RUN_TEST(test_receive_control_msg);
@@ -1434,8 +1303,6 @@ void run_test(int argc, char **argv)
init_port(PORT0, PD_REV30);
RUN_TEST(test_prl_reset);
RUN_TEST(test_send_ctrl_msg);
- RUN_TEST(test_send_ctrl_msg_with_retry_and_fail);
- RUN_TEST(test_send_ctrl_msg_with_retry_and_success);
RUN_TEST(test_send_data_msg);
RUN_TEST(test_send_data_msg_to_much_data);
RUN_TEST(test_send_extended_data_msg);
diff --git a/test/usb_tcpmv2_tcpci.c b/test/usb_tcpmv2_tcpci.c
index 84bedd3e66..b383791faf 100644
--- a/test/usb_tcpmv2_tcpci.c
+++ b/test/usb_tcpmv2_tcpci.c
@@ -12,6 +12,7 @@
#include "timer.h"
#include "usb_mux.h"
#include "usb_tc_sm.h"
+#include "usb_prl_sm.h"
#define PORT0 0
@@ -167,8 +168,8 @@ __maybe_unused static int test_connect_as_pd3_source(void)
/*
* c) The Tester waits for Source_Capabilities for tNoResponse max.
*/
- TEST_EQ(mock_tcpci_wait_for_transmit(
- TCPC_TX_SOP, 0, PD_DATA_SOURCE_CAP), EC_SUCCESS, "%d");
+ TEST_EQ(verify_tcpci_transmit(TCPC_TX_SOP, 0, PD_DATA_SOURCE_CAP),
+ EC_SUCCESS, "%d");
/*
* d) The Tester replies GoodCrc on reception of the
* Source_Capabilities.
@@ -184,14 +185,14 @@ __maybe_unused static int test_connect_as_pd3_source(void)
1, PD_REV30, 0),
&rdo);
mock_set_alert(TCPC_REG_ALERT_RX_STATUS);
- TEST_EQ(mock_tcpci_wait_for_transmit(
- TCPC_TX_SOP, PD_CTRL_ACCEPT, 0), EC_SUCCESS, "%d");
+ TEST_EQ(verify_tcpci_transmit(TCPC_TX_SOP, PD_CTRL_ACCEPT, 0),
+ EC_SUCCESS, "%d");
mock_set_alert(TCPC_REG_ALERT_TX_SUCCESS);
/*
* f) The Tester waits for PS_RDY for tPSSourceOn max.
*/
- TEST_EQ(mock_tcpci_wait_for_transmit(
- TCPC_TX_SOP, PD_CTRL_PS_RDY, 0), EC_SUCCESS, "%d");
+ TEST_EQ(verify_tcpci_transmit(TCPC_TX_SOP, PD_CTRL_PS_RDY, 0),
+ EC_SUCCESS, "%d");
mock_set_alert(TCPC_REG_ALERT_TX_SUCCESS);
/*
@@ -201,8 +202,8 @@ __maybe_unused static int test_connect_as_pd3_source(void)
* the test fails. During this period, the Tester replies any message
* sent from the UUT with a proper response.
*/
- TEST_EQ(mock_tcpci_wait_for_transmit(
- TCPC_TX_SOP_PRIME, 0, PD_DATA_VENDOR_DEF), EC_SUCCESS, "%d");
+ TEST_EQ(verify_tcpci_transmit(TCPC_TX_SOP_PRIME, 0, PD_DATA_VENDOR_DEF),
+ EC_SUCCESS, "%d");
mock_set_alert(TCPC_REG_ALERT_TX_SUCCESS);
task_wait_event(10 * MSEC);
mock_tcpci_receive(PD_MSG_SOP_PRIME,
@@ -212,8 +213,8 @@ __maybe_unused static int test_connect_as_pd3_source(void)
NULL);
mock_set_alert(TCPC_REG_ALERT_RX_STATUS);
- TEST_EQ(mock_tcpci_wait_for_transmit(
- TCPC_TX_SOP, 0, PD_DATA_VENDOR_DEF), EC_SUCCESS, "%d");
+ TEST_EQ(verify_tcpci_transmit(TCPC_TX_SOP, 0, PD_DATA_VENDOR_DEF),
+ EC_SUCCESS, "%d");
mock_set_alert(TCPC_REG_ALERT_TX_SUCCESS);
task_wait_event(10 * MSEC);
mock_tcpci_receive(PD_MSG_SOP,
@@ -232,6 +233,77 @@ __maybe_unused static int test_connect_as_pd3_source(void)
return EC_SUCCESS;
}
+__maybe_unused static int test_retry_count_sop(void)
+{
+ /* DRP auto-toggling with AP in S0, source enabled. */
+ TEST_EQ(test_startup_and_resume(), EC_SUCCESS, "%d");
+
+ /*
+ * The test starts in a disconnected state.
+ */
+ mock_tcpci_set_reg(TCPC_REG_EXT_STATUS, TCPC_REG_EXT_STATUS_SAFE0V);
+ mock_set_alert(TCPC_REG_ALERT_EXT_STATUS);
+ task_wait_event(10 * SECOND);
+
+ /*
+ * The Tester applies Rd and waits for Vbus for tNoResponse max.
+ */
+ mock_set_cc(MOCK_CC_WE_ARE_SRC, MOCK_CC_SRC_OPEN, MOCK_CC_SRC_RD);
+ mock_set_alert(TCPC_REG_ALERT_CC_STATUS);
+
+ /*
+ * The Tester waits for Source_Capabilities for tNoResponse max.
+ *
+ * Source Caps is SOP message which should be retried at TCPC layer
+ */
+ TEST_EQ(verify_tcpci_tx_retry_count(CONFIG_PD_RETRY_COUNT), EC_SUCCESS,
+ "%d");
+ return EC_SUCCESS;
+}
+
+__maybe_unused static int test_retry_count_hard_reset(void)
+{
+ /* DRP auto-toggling with AP in S0, source enabled. */
+ TEST_EQ(test_startup_and_resume(), EC_SUCCESS, "%d");
+
+ /*
+ * The test starts in a disconnected state.
+ */
+ mock_tcpci_set_reg(TCPC_REG_EXT_STATUS, TCPC_REG_EXT_STATUS_SAFE0V);
+ mock_set_alert(TCPC_REG_ALERT_EXT_STATUS);
+ task_wait_event(10 * SECOND);
+
+ /*
+ * The Tester applies Rd and waits for Vbus for tNoResponse max.
+ */
+ mock_set_cc(MOCK_CC_WE_ARE_SRC, MOCK_CC_SRC_OPEN, MOCK_CC_SRC_RD);
+ mock_set_alert(TCPC_REG_ALERT_CC_STATUS);
+
+ /*
+ * The Tester waits for Source_Capabilities for tNoResponse max.
+ */
+ TEST_EQ(verify_tcpci_transmit(TCPC_TX_SOP, 0, PD_DATA_SOURCE_CAP),
+ EC_SUCCESS, "%d");
+ /*
+ * The Tester replies GoodCrc on reception of the Source_Capabilities.
+ */
+ mock_set_alert(TCPC_REG_ALERT_TX_SUCCESS);
+ task_wait_event(10 * MSEC);
+
+ /*
+ * Now that PRL is running since we are connected, we can send a hard
+ * reset.
+ */
+
+ /* Request that DUT send hard reset */
+ prl_execute_hard_reset(PORT0);
+
+ /* The retry count for hard resets should be 0 */
+ TEST_EQ(verify_tcpci_tx_retry_count(0), EC_SUCCESS, "%d");
+
+ return EC_SUCCESS;
+}
+
void before_test(void)
{
mock_usb_mux_reset();
@@ -249,6 +321,8 @@ void run_test(int argc, char **argv)
RUN_TEST(test_connect_as_nonpd_sink);
RUN_TEST(test_startup_and_resume);
RUN_TEST(test_connect_as_pd3_source);
+ RUN_TEST(test_retry_count_sop);
+ RUN_TEST(test_retry_count_hard_reset);
test_print_result();
}