summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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();
}