summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbe Levkoy <alevkoy@chromium.org>2021-05-04 11:49:25 -0600
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-05-03 00:39:28 +0000
commit8c00b75df04d7e7f25e47f08bf9b757226ade333 (patch)
treeeca029e80d36ff6a2f9e2754eb7972ba9b614762
parent6ced9f0662c02a47acc4d82088aefc04340f1891 (diff)
downloadchrome-ec-8c00b75df04d7e7f25e47f08bf9b757226ade333.tar.gz
TCPMv2: Support Data Reset as DFP, recipient
Support receiving Data_Reset as DFP. BUG=b:141363146 TEST=Observe Data Resets from voxel (UFP) to lindar (DFP) with each as VCONN Source. BRANCH=none Signed-off-by: Abe Levkoy <alevkoy@chromium.org> Change-Id: Ibe747dbc04cea0d787b3471627b940f1405ee8be Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2871058 Reviewed-by: Diana Z <dzigterman@chromium.org>
-rw-r--r--common/usbc/usb_pe_drp_sm.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c
index 97a1d42f64..bc3dcf48e7 100644
--- a/common/usbc/usb_pe_drp_sm.c
+++ b/common/usbc/usb_pe_drp_sm.c
@@ -264,6 +264,7 @@ enum usb_pe_state {
/* PD3.0 only states below here*/
/* DFP Data Reset States */
PE_DDR_SEND_DATA_RESET,
+ PE_DDR_DATA_RESET_RECEIVED,
PE_DDR_WAIT_FOR_VCONN_OFF,
PE_DDR_PERFORM_DATA_RESET,
PE_FRS_SNK_SRC_START_AMS,
@@ -403,6 +404,7 @@ __maybe_unused static __const_data const char * const pe_state_names[] = {
#endif
#ifdef CONFIG_USB_PD_DATA_RESET_MSG
[PE_DDR_SEND_DATA_RESET] = "PE_DDR_Send_Data_Reset",
+ [PE_DDR_DATA_RESET_RECEIVED] = "PE_DDR_Data_Reset_Received",
[PE_DDR_WAIT_FOR_VCONN_OFF] = "PE_DDR_Wait_For_VCONN_Off",
[PE_DDR_PERFORM_DATA_RESET] = "PE_DDR_Perform_Data_Reset",
#endif /* CONFIG_USB_PD_DATA_RESET_MSG */
@@ -461,6 +463,8 @@ GEN_NOT_SUPPORTED(PE_SNK_CHUNK_RECEIVED);
#ifndef CONFIG_USB_PD_DATA_RESET_MSG
GEN_NOT_SUPPORTED(PE_DDR_SEND_DATA_RESET);
#define PE_DDR_SEND_DATA_RESET PE_DDR_SEND_DATA_RESET_NOT_SUPPORTED
+GEN_NOT_SUPPORTED(PE_DDR_DATA_RESET_RECEIVED);
+#define PE_DDR_DATA_RESET_RECEIVED PE_DDR_DATA_RESET_RECEIVED_NOT_SUPPORTED
GEN_NOT_SUPPORTED(PE_DDR_WAIT_FOR_VCONN_OFF);
#define PE_DDR_WAIT_FOR_VCONN_OFF PE_DDR_WAIT_FOR_VCONN_OFF_NOT_SUPPORTED
GEN_NOT_SUPPORTED(PE_DDR_PERFORM_DATA_RESET);
@@ -1145,6 +1149,7 @@ void pe_report_error(int port, enum pe_error e, enum tcpci_msg_type type)
get_state_pe(port) == PE_VDM_IDENTITY_REQUEST_CBL) ||
(IS_ENABLED(CONFIG_USB_PD_DATA_RESET_MSG) &&
(get_state_pe(port) == PE_DDR_SEND_DATA_RESET ||
+ get_state_pe(port) == PE_DDR_DATA_RESET_RECEIVED ||
get_state_pe(port) == PE_DDR_WAIT_FOR_VCONN_OFF ||
get_state_pe(port) == PE_DDR_PERFORM_DATA_RESET)) ||
(pe_in_frs_mode(port) &&
@@ -2735,6 +2740,19 @@ static void pe_src_ready_run(int port)
pe_send_soft_reset(port,
PD_HEADER_GET_SOP(rx_emsg[port].header));
return;
+#ifdef CONFIG_USB_PD_DATA_RESET_MSG
+ case PD_CTRL_DATA_RESET:
+ if (pe[port].data_role == PD_ROLE_DFP)
+ set_state_pe(port,
+ PE_DDR_DATA_RESET_RECEIVED);
+ /*
+ * TODO(b/209628496): Support Data Reset as UFP
+ */
+ else
+ set_state_pe(port,
+ PE_SEND_NOT_SUPPORTED);
+ return;
+#endif /* CONFIG_USB_PD_DATA_RESET_MSG */
/*
* Receiving an unknown or unsupported message
* shall be responded to with a not supported message.
@@ -3552,6 +3570,19 @@ static void pe_snk_ready_run(int port)
set_state_pe(port,
PE_SEND_NOT_SUPPORTED);
return;
+#ifdef CONFIG_USB_PD_DATA_RESET_MSG
+ case PD_CTRL_DATA_RESET:
+ if (pe[port].data_role == PD_ROLE_DFP)
+ set_state_pe(port,
+ PE_DDR_DATA_RESET_RECEIVED);
+ /*
+ * TODO(b/209628496): Support Data Reset as UFP
+ */
+ else
+ set_state_pe(port,
+ PE_SEND_NOT_SUPPORTED);
+ return;
+#endif /* CONFIG_USB_PD_DATA_RESET_MSG */
case PD_CTRL_NOT_SUPPORTED:
/* Do nothing */
break;
@@ -7121,6 +7152,40 @@ static void pe_ddr_send_data_reset_exit(int port)
}
/*
+ * PE_DDR_Data_Reset_Received
+ */
+static void pe_ddr_data_reset_received_entry(int port)
+{
+ print_current_state(port);
+ /* Send Data Reset message */
+ send_ctrl_msg(port, TCPCI_MSG_SOP, PD_CTRL_ACCEPT);
+}
+
+static void pe_ddr_data_reset_received_run(int port)
+{
+ if (PE_CHK_FLAG(port, PE_FLAGS_TX_COMPLETE)) {
+ PE_CLR_FLAG(port, PE_FLAGS_TX_COMPLETE);
+ if (tc_is_vconn_src(port))
+ set_state_pe(port, PE_DDR_PERFORM_DATA_RESET);
+ else
+ set_state_pe(port, PE_DDR_WAIT_FOR_VCONN_OFF);
+ } else if (PE_CHK_FLAG(port, PE_FLAGS_PROTOCOL_ERROR)) {
+ PE_CLR_FLAG(port, PE_FLAGS_PROTOCOL_ERROR);
+ set_state_pe(port, PE_WAIT_FOR_ERROR_RECOVERY);
+ }
+}
+
+static void pe_ddr_data_reset_received_exit(int port)
+{
+ /*
+ * Start DataResetFailTimer
+ * NOTE: This timer continues to run in every state until it is stopped
+ * or it times out.
+ */
+ pd_timer_enable(port, PE_TIMER_DATA_RESET_FAIL, PD_T_DATA_RESET_FAIL);
+}
+
+/*
* PE_DDR_Wait_For_VCONN_Off
*/
static void pe_ddr_wait_for_vconn_off_entry(int port)
@@ -7774,6 +7839,11 @@ static __const_data const struct usb_state pe_states[] = {
.run = pe_ddr_send_data_reset_run,
.exit = pe_ddr_send_data_reset_exit,
},
+ [PE_DDR_DATA_RESET_RECEIVED] = {
+ .entry = pe_ddr_data_reset_received_entry,
+ .run = pe_ddr_data_reset_received_run,
+ .exit = pe_ddr_data_reset_received_exit,
+ },
[PE_DDR_WAIT_FOR_VCONN_OFF] = {
.entry = pe_ddr_wait_for_vconn_off_entry,
.run = pe_ddr_wait_for_vconn_off_run,