diff options
author | Sam Hurst <shurst@google.com> | 2020-04-02 19:14:34 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-05-02 07:21:15 +0000 |
commit | 220feed8668d94077900a6293e385c0e6a636205 (patch) | |
tree | 8b02201e5d136462fbd4ea3c286c28849b67ebff | |
parent | 6071cb1e1682796730f1f77072ae75c51b61c4f9 (diff) | |
download | chrome-ec-220feed8668d94077900a6293e385c0e6a636205.tar.gz |
TCPMv2: Send Soft Reset to SOP* that caused a protocol error
On a protocol error, sends soft reset to SOP* of
incoming or outgoing message.
BUG=b:150614211
BRANCH=none
TEST=make -j buildall
Manual tests:
Passed FAFT_PD on hatch. Port partner was SOP
Modified FAFT_PD test to send soft reset from SOP'
All tests passed
Change-Id: Ic9832fe3b9efd6f313cbfde74cfa3a7922121678
Signed-off-by: Sam Hurst <shurst@google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2135328
Reviewed-by: Diana Z <dzigterman@chromium.org>
-rw-r--r-- | common/usbc/usb_pe_ctvpd_sm.c | 2 | ||||
-rw-r--r-- | common/usbc/usb_pe_drp_sm.c | 45 | ||||
-rw-r--r-- | common/usbc/usb_prl_sm.c | 15 | ||||
-rw-r--r-- | include/usb_pe_sm.h | 4 | ||||
-rw-r--r-- | test/usb_prl.c | 4 |
5 files changed, 45 insertions, 25 deletions
diff --git a/common/usbc/usb_pe_ctvpd_sm.c b/common/usbc/usb_pe_ctvpd_sm.c index 96afc42f49..7e215e4113 100644 --- a/common/usbc/usb_pe_ctvpd_sm.c +++ b/common/usbc/usb_pe_ctvpd_sm.c @@ -98,7 +98,7 @@ void pe_got_hard_reset(int port) /* No implementation needed by this policy engine */ } -void pe_report_error(int port, enum pe_error e) +void pe_report_error(int port, enum pe_error e, enum tcpm_transmit_type type) { /* No implementation needed by this policy engine */ } diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c index 4f80eb72f4..2402654868 100644 --- a/common/usbc/usb_pe_drp_sm.c +++ b/common/usbc/usb_pe_drp_sm.c @@ -366,6 +366,9 @@ static struct policy_engine { /* last requested voltage PDO index */ int requested_idx; + /* port address where soft resets are sent */ + enum tcpm_transmit_type soft_reset_sop; + /* Current limit / voltage based on the last request message */ uint32_t curr_limit; uint32_t supply_voltage; @@ -782,7 +785,13 @@ static bool pe_can_send_sop_vdm(int port, int vdm_cmd) return false; } -void pe_report_error(int port, enum pe_error e) +static void pe_send_soft_reset(const int port, enum tcpm_transmit_type type) +{ + pe[port].soft_reset_sop = type; + set_state_pe(port, PE_SEND_SOFT_RESET); +} + +void pe_report_error(int port, enum pe_error e, enum tcpm_transmit_type type) { /* This should only be called from the PD task */ assert(port == TASK_ID_TO_PD_PORT(task_get_current())); @@ -831,7 +840,7 @@ void pe_report_error(int port, enum pe_error e) if (!PE_CHK_FLAG(port, PE_FLAGS_EXPLICIT_CONTRACT) && (!PE_CHK_FLAG(port, PE_FLAGS_INTERRUPTIBLE_AMS) || (e == ERR_TCH_XMIT))) { - set_state_pe(port, PE_SEND_SOFT_RESET); + pe_send_soft_reset(port, type); } /* * Transition to PE_Snk_Ready or PE_Src_Ready by a Protocol @@ -986,7 +995,8 @@ static bool common_src_snk_dpm_requests(int port) DPM_REQUEST_SOFT_RESET_SEND)) { PE_CLR_DPM_REQUEST(port, DPM_REQUEST_SOFT_RESET_SEND); - set_state_pe(port, PE_SEND_SOFT_RESET); + /* Currently only support sending soft reset to SOP */ + pe_send_soft_reset(port, TCPC_TX_SOP); return true; } else if (PE_CHK_DPM_REQUEST(port, DPM_REQUEST_PORT_DISCOVERY)) { @@ -1527,13 +1537,14 @@ static void pe_src_send_capabilities_run(int port) * PE_SNK/SRC_READY if explicit contract * PE_SEND_SOFT_RESET otherwise */ - if (PE_CHK_FLAG(port, PE_FLAGS_EXPLICIT_CONTRACT)) + if (PE_CHK_FLAG(port, PE_FLAGS_EXPLICIT_CONTRACT)) { if (pe[port].power_role == PD_ROLE_SINK) set_state_pe(port, PE_SNK_READY); else set_state_pe(port, PE_SRC_READY); - else - set_state_pe(port, PE_SEND_SOFT_RESET); + } else { + pe_send_soft_reset(port, TCPC_TX_SOP); + } return; } @@ -2154,7 +2165,7 @@ static void pe_snk_startup_run(int port) * is entered. */ sysjump_occurred = false; - set_state_pe(port, PE_SEND_SOFT_RESET); + pe_send_soft_reset(port, TCPC_TX_SOP); } else { /* * Once the reset process completes, the Policy Engine Shall @@ -2298,6 +2309,7 @@ static void pe_snk_select_capability_run(int port) { uint8_t type; uint8_t cnt; + enum tcpm_transmit_type sop; /* Wait until message is sent */ if (pe[port].sender_response_timer == TIMER_DISABLED) { @@ -2315,6 +2327,7 @@ static void pe_snk_select_capability_run(int port) PE_CLR_FLAG(port, PE_FLAGS_MSG_RECEIVED); type = PD_HEADER_TYPE(rx_emsg[port].header); cnt = PD_HEADER_CNT(rx_emsg[port].header); + sop = PD_HEADER_GET_SOP(rx_emsg[port].header); /* * Transition to the PE_SNK_Transition_Sink state when: @@ -2383,7 +2396,7 @@ static void pe_snk_select_capability_run(int port) */ else { /* Send Soft Reset */ - set_state_pe(port, PE_SEND_SOFT_RESET); + pe_send_soft_reset(port, sop); return; } } @@ -2392,7 +2405,7 @@ static void pe_snk_select_capability_run(int port) */ else { /* Send Soft Reset */ - set_state_pe(port, PE_SEND_SOFT_RESET); + pe_send_soft_reset(port, sop); return; } } @@ -2829,7 +2842,8 @@ static void pe_send_soft_reset_run(int port) * unexpected incoming message type */ /* Send Soft Reset message */ - prl_send_ctrl_msg(port, TCPC_TX_SOP, PD_CTRL_SOFT_RESET); + prl_send_ctrl_msg(port, + pe[port].soft_reset_sop, PD_CTRL_SOFT_RESET); /* Initialize and run SenderResponseTimer */ pe[port].sender_response_timer = @@ -4143,7 +4157,7 @@ static void pe_vdm_identity_request_cbl_run(int port) /* Message received */ if (PE_CHK_FLAG(port, PE_FLAGS_MSG_RECEIVED)) { uint32_t *payload; - int sop; + enum tcpm_transmit_type sop; uint8_t type; uint8_t cnt; uint8_t ext; @@ -4224,7 +4238,7 @@ static void pe_vdm_identity_request_cbl_run(int port) * incoming message */ if (get_last_state_pe(port) == PE_SRC_DISCOVERY) { - set_state_pe(port, PE_SEND_SOFT_RESET); + pe_send_soft_reset(port, sop); } else { /* * Otherwise, return to PE_S[RC,NK]_Ready to process @@ -4836,6 +4850,7 @@ static void pe_vcs_send_swap_run(int port) { uint8_t type; uint8_t cnt; + enum tcpm_transmit_type sop; /* Wait until message is sent */ if (pe[port].sender_response_timer == TIMER_DISABLED && @@ -4854,6 +4869,7 @@ static void pe_vcs_send_swap_run(int port) type = PD_HEADER_TYPE(rx_emsg[port].header); cnt = PD_HEADER_CNT(rx_emsg[port].header); + sop = PD_HEADER_GET_SOP(rx_emsg[port].header); /* Only look at control messages */ if (cnt == 0) { @@ -4894,7 +4910,7 @@ static void pe_vcs_send_swap_run(int port) */ else { /* Send Soft Reset */ - set_state_pe(port, PE_SEND_SOFT_RESET); + pe_send_soft_reset(port, sop); return; } } @@ -5029,7 +5045,6 @@ static void pe_vcs_send_ps_rdy_swap_entry(int port) /* Send a PS_RDY Message */ prl_send_ctrl_msg(port, TCPC_TX_SOP, PD_CTRL_PS_RDY); - pe[port].sub = PE_SUB0; } @@ -5085,7 +5100,7 @@ static void pe_vcs_send_ps_rdy_swap_run(int port) if (pe[port].sub == PE_SUB0) { /* PS_RDY didn't send, soft reset */ - set_state_pe(port, PE_SEND_SOFT_RESET); + pe_send_soft_reset(port, TCPC_TX_SOP); } else { /* * Cable plug wasn't present, diff --git a/common/usbc/usb_prl_sm.c b/common/usbc/usb_prl_sm.c index 8b375abfab..23282d4e22 100644 --- a/common/usbc/usb_prl_sm.c +++ b/common/usbc/usb_prl_sm.c @@ -174,6 +174,8 @@ static struct tx_chunked { /* Message Reception State Machine Object */ static struct protocol_layer_rx { + /* received message type */ + enum tcpm_transmit_type sop; /* message ids for all valid port partners */ int msg_id[NUM_SOP_STAR_TYPES]; } prl_rx[CONFIG_USB_PD_PORT_MAX_COUNT]; @@ -1254,10 +1256,10 @@ static void rch_report_error_entry(const int port) /* Pass Message to Policy Engine */ pe_message_received(port); /* Report error */ - pe_report_error(port, ERR_RCH_MSG_REC); + pe_report_error(port, ERR_RCH_MSG_REC, prl_rx[port].sop); } else { /* Report error */ - pe_report_error(port, ERR_RCH_CHUNKED); + pe_report_error(port, ERR_RCH_CHUNKED, prl_rx[port].sop); } } @@ -1555,7 +1557,7 @@ static void tch_message_sent_entry(const int port) static void tch_report_error_entry(const int port) { /* Report Error To Policy Engine */ - pe_report_error(port, tch[port].error); + pe_report_error(port, tch[port].error, prl_tx[port].last_xmit_type); set_state_tch(port, TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE); } @@ -1567,7 +1569,6 @@ static void prl_rx_wait_for_phy_message(const int port, int evt) uint32_t header; uint8_t type; uint8_t cnt; - uint8_t sop; int8_t msid; /* If we don't have any message, just stop processing now. */ @@ -1579,7 +1580,7 @@ static void prl_rx_wait_for_phy_message(const int port, int evt) type = PD_HEADER_TYPE(header); cnt = PD_HEADER_CNT(header); msid = PD_HEADER_ID(header); - sop = PD_HEADER_GET_SOP(header); + prl_rx[port].sop = PD_HEADER_GET_SOP(header); /* Make sure an incorrect count doesn't overflow the chunk buffer */ if (cnt > CHK_BUF_SIZE) @@ -1628,7 +1629,7 @@ static void prl_rx_wait_for_phy_message(const int port, int evt) /* * Ignore if this is a duplicate message. Stop processing. */ - if (prl_rx[port].msg_id[sop] == msid) + if (prl_rx[port].msg_id[prl_rx[port].sop] == msid) return; /* @@ -1644,7 +1645,7 @@ static void prl_rx_wait_for_phy_message(const int port, int evt) } /* Store Message Id */ - prl_rx[port].msg_id[sop] = msid; + prl_rx[port].msg_id[prl_rx[port].sop] = msid; /* RTR Chunked Message Router States. */ /* diff --git a/include/usb_pe_sm.h b/include/usb_pe_sm.h index 26427f23d5..771b4d408b 100644 --- a/include/usb_pe_sm.h +++ b/include/usb_pe_sm.h @@ -8,6 +8,7 @@ #ifndef __CROS_EC_USB_PE_H #define __CROS_EC_USB_PE_H +#include "usb_pd_tcpm.h" #include "usb_sm.h" /* Policy Engine Receive and Transmit Errors */ @@ -72,8 +73,9 @@ void pe_message_sent(int port); * * @param port USB-C port number * @param e error + * @param type port address where error was generated */ -void pe_report_error(int port, enum pe_error e); +void pe_report_error(int port, enum pe_error e, enum tcpm_transmit_type type); /** * Called by the Protocol Layer to informs the Policy Engine diff --git a/test/usb_prl.c b/test/usb_prl.c index f0d71a75d2..e169fc2f05 100644 --- a/test/usb_prl.c +++ b/test/usb_prl.c @@ -99,6 +99,7 @@ static struct pd_prl { enum pd_data_role data_role; int msg_tx_id; int msg_rx_id; + enum tcpm_transmit_type sop; int mock_pe_message_sent; int mock_pe_error; @@ -737,9 +738,10 @@ enum pd_cable_plug tc_get_cable_plug(int port) return PD_PLUG_FROM_DFP_UFP; } -void pe_report_error(int port, enum pe_error e) +void pe_report_error(int port, enum pe_error e, enum tcpm_transmit_type type) { pd_port[port].mock_pe_error = e; + pd_port[port].sop = type; } void pe_got_hard_reset(int port) |