diff options
-rw-r--r-- | board/servo_v4p1/fusb302b.h | 3 | ||||
-rw-r--r-- | common/mock/tcpci_i2c_mock.c | 40 | ||||
-rw-r--r-- | common/usb_pd_protocol.c | 3 | ||||
-rw-r--r-- | common/usb_pd_tcpc.c | 3 | ||||
-rw-r--r-- | common/usbc/usb_prl_sm.c | 100 | ||||
-rw-r--r-- | driver/tcpm/fusb302.c | 3 | ||||
-rw-r--r-- | driver/tcpm/fusb302.h | 3 | ||||
-rw-r--r-- | driver/tcpm/it83xx.c | 4 | ||||
-rw-r--r-- | driver/tcpm/it8xxx2.c | 4 | ||||
-rw-r--r-- | driver/tcpm/tcpci.c | 14 | ||||
-rw-r--r-- | driver/tcpm/tcpci.h | 2 | ||||
-rw-r--r-- | include/config.h | 16 | ||||
-rw-r--r-- | include/mock/tcpci_i2c_mock.h | 8 | ||||
-rw-r--r-- | include/usb_pd_tcpm.h | 3 | ||||
-rw-r--r-- | include/usb_prl_sm.h | 5 | ||||
-rw-r--r-- | test/usb_prl_old.c | 133 | ||||
-rw-r--r-- | test/usb_tcpmv2_tcpci.c | 94 |
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 |= 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(); } |