TCPMv2: Soft reset on failure to send source caps

pe_report_error() defers to PE_SRC_SEND_CAPABILITIES for custom
error handling (via PE_FLAGS_PROTOCOL_ERROR).

pe_src_send_capabilities_run() was correctly going to PE_SRC_DISCOVERY
when we are not connected (PD 3.0 8.3.3.2.3), but it was failing to
send soft reset when we are already connected (PD 3.0 8.3.3.4.1.1).

BUG=b:161835483
BRANCH=none
TEST=make run-usb_pe_drp
     PD 3.0 compliance test TD.PD.SRC3.E26
	(Soft_Reset sent regardless of Rp value)

Signed-off-by: Edward Hill <ecgh@chromium.org>
Change-Id: Id71e38a69006e95b7ff4f7145e86bd5ac64c7577
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2321869
Reviewed-by: Jett Rink <jettrink@chromium.org>
This commit is contained in:
Edward Hill 2020-07-27 19:01:55 -06:00 committed by Commit Bot
parent 0f93e28bc7
commit 44504b4e0a
3 changed files with 49 additions and 5 deletions

View File

@ -1781,14 +1781,22 @@ static void pe_src_send_capabilities_run(int port)
* 1) The Protocol Layer indicates that the Message has not been sent
* and we are presently not Connected
*
* Send soft reset when:
* 1) The Protocol Layer indicates that the Message has not been sent
* and we are already Connected
*
* 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.
*
* NOTE: The PE_FLAGS_PROTOCOL_ERROR is set if a GoodCRC Message
* is not received.
*/
if (PE_CHK_FLAG(port, PE_FLAGS_PROTOCOL_ERROR) &&
!PE_CHK_FLAG(port, PE_FLAGS_PD_CONNECTION)) {
if (PE_CHK_FLAG(port, PE_FLAGS_PROTOCOL_ERROR)) {
PE_CLR_FLAG(port, PE_FLAGS_PROTOCOL_ERROR);
set_state_pe(port, PE_SRC_DISCOVERY);
if (!PE_CHK_FLAG(port, PE_FLAGS_PD_CONNECTION))
set_state_pe(port, PE_SRC_DISCOVERY);
else
pe_send_soft_reset(port, TCPC_TX_SOP);
return;
}

View File

@ -27,7 +27,7 @@ void prl_hard_reset_complete(int port)
int prl_is_running(int port)
{
return 0;
return 1;
}
void prl_reset(int port)

View File

@ -278,6 +278,41 @@ test_static int test_extended_message_not_supported_snk(void)
return test_extended_message_not_supported();
}
static int test_send_caps_error(void)
{
/*
* 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.
*
* Transition to the PE_SRC_Discovery state when:
* 1) The Protocol Layer indicates that the Message has not been sent
* and we are presently not Connected
*/
fake_prl_clear_last_sent_ctrl_msg(PORT0);
pe_set_flag(PORT0, PE_FLAGS_PROTOCOL_ERROR);
pe_clr_flag(PORT0, PE_FLAGS_PD_CONNECTION);
set_state_pe(PORT0, PE_SRC_SEND_CAPABILITIES);
task_wait_event(10 * MSEC);
TEST_EQ(fake_prl_get_last_sent_ctrl_msg(PORT0), 0, "%d");
TEST_EQ(get_state_pe(PORT0), PE_SRC_DISCOVERY, "%d");
/*
* Send soft reset when:
* 1) The Protocol Layer indicates that the Message has not been sent
* and we are already Connected
*/
fake_prl_clear_last_sent_ctrl_msg(PORT0);
pe_set_flag(PORT0, PE_FLAGS_PROTOCOL_ERROR);
pe_set_flag(PORT0, PE_FLAGS_PD_CONNECTION);
set_state_pe(PORT0, PE_SRC_SEND_CAPABILITIES);
task_wait_event(10 * MSEC);
TEST_EQ(fake_prl_get_last_sent_ctrl_msg(PORT0),
PD_CTRL_SOFT_RESET, "%d");
TEST_EQ(get_state_pe(PORT0), PE_SEND_SOFT_RESET, "%d");
return EC_SUCCESS;
}
void run_test(int argc, char **argv)
{
test_reset();
@ -288,6 +323,7 @@ void run_test(int argc, char **argv)
RUN_TEST(test_extended_message_not_supported_src);
RUN_TEST(test_extended_message_not_supported_snk);
#endif
RUN_TEST(test_send_caps_error);
/* Do basic state machine validity checks last. */
RUN_TEST(test_pe_no_parent_cycles);