From d71c268f773fd485e4126b1ea184d7da34d9543f Mon Sep 17 00:00:00 2001 From: Denis Brockus Date: Tue, 27 Aug 2019 09:11:35 -0600 Subject: pd: Chunked TX State Machine changes Comment when TCH states are embedded. TCH_Message_Sent and TCH_Report_Error states were redundantly implemented inline. I added these states so it would match the spec more closely. BUG=none BRANCH=none TEST=make buildall -j Change-Id: Ib911aa8ac99be5eb0372e55b658a0542c02596fd Signed-off-by: Denis Brockus Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1773132 Reviewed-by: Jett Rink --- common/usbc/usb_prl_sm.c | 108 ++++++++++++++++++++++++++++------------------- test/usb_prl.c | 2 + 2 files changed, 67 insertions(+), 43 deletions(-) diff --git a/common/usbc/usb_prl_sm.c b/common/usbc/usb_prl_sm.c index 30401aeb27..fa6759edaf 100644 --- a/common/usbc/usb_prl_sm.c +++ b/common/usbc/usb_prl_sm.c @@ -109,6 +109,8 @@ enum usb_tch_state { TCH_SENDING_CHUNKED_MESSAGE, TCH_WAIT_CHUNK_REQUEST, TCH_MESSAGE_RECEIVED, + TCH_MESSAGE_SENT, + TCH_REPORT_ERROR, }; /* Forward declare full list of states. Index by above enums. */ @@ -136,6 +138,8 @@ static struct tx_chunked { uint32_t flags; /* protocol timer */ uint64_t chunk_sender_request_timer; + /* error to report when moving to tch_report_error state */ + enum pe_error error; } tch[CONFIG_USB_PD_PORT_COUNT]; /* Message Reception State Machine Object */ @@ -680,17 +684,15 @@ static void prl_tx_wait_for_phy_response_run(const int port) /* Increment message id counter */ increment_msgid_counter(port); set_state_prl_tx(port, PRL_TX_WAIT_FOR_MESSAGE_REQUEST); - return; + } else { + /* + * NOTE: PRL_TX_Construct_Message State embedded + * here. + */ + /* Try to resend the message. */ + prl_tx_construct_message(port); } - - /* Try to resend the message. */ - /* NOTE: PRL_TX_Construct_Message State embedded here. */ - prl_tx_construct_message(port); - return; - } - - if (prl_tx[port].xmit_status == TCPC_TX_COMPLETE_SUCCESS) { - + } else if (prl_tx[port].xmit_status == TCPC_TX_COMPLETE_SUCCESS) { /* NOTE: PRL_TX_Message_Sent State embedded here. */ /* Increment messageId counter */ @@ -698,7 +700,6 @@ static void prl_tx_wait_for_phy_response_run(const int port) /* Inform Policy Engine Message was sent */ PDMSG_SET_FLAG(port, PRL_FLAGS_TX_COMPLETE); set_state_prl_tx(port, PRL_TX_WAIT_FOR_MESSAGE_REQUEST); - return; } } @@ -907,6 +908,9 @@ static void copy_chunk_to_ext(int port) /* * Chunked Rx State Machine */ +/* + * RchWaitForMessageFromProtocolLayer + */ static void rch_wait_for_message_from_protocol_layer_entry(const int port) { /* Clear Abort flag */ @@ -1188,7 +1192,11 @@ static void rch_report_error_run(const int port) /* * Chunked Tx State Machine */ -static inline void tch_clear_abort_set_chunking(int port) + +/* + * TchWaitForMessageRequestFromPe + */ +static void tch_wait_for_message_request_from_pe_entry(const int port) { /* Clear Abort flag */ PDMSG_CLR_FLAG(port, PRL_FLAGS_ABORT); @@ -1197,11 +1205,6 @@ static inline void tch_clear_abort_set_chunking(int port) tch[port].flags = PRL_FLAGS_CHUNKING; } -static void tch_wait_for_message_request_from_pe_entry(const int port) -{ - tch_clear_abort_set_chunking(port); -} - static void tch_wait_for_message_request_from_pe_run(const int port) { /* @@ -1220,15 +1223,18 @@ static void tch_wait_for_message_request_from_pe_run(const int port) */ if (rch_get_state(port) != RCH_WAIT_FOR_MESSAGE_FROM_PROTOCOL_LAYER) { - /* Report Error To Policy Engine */ - pe_report_error(port, ERR_TCH_XMIT); - tch_clear_abort_set_chunking(port); + tch[port].error = ERR_TCH_XMIT; + set_state_tch(port, TCH_REPORT_ERROR); } else { /* * Extended Message Request & Chunking */ if ((pdmsg[port].rev == PD_REV30) && pdmsg[port].ext && TCH_CHK_FLAG(port, PRL_FLAGS_CHUNKING)) { + /* + * NOTE: TCH_Prepare_To_Send_Chunked_Message + * embedded here. + */ pdmsg[port].send_offset = 0; pdmsg[port].chunk_number_to_send = 0; set_state_tch(port, @@ -1240,15 +1246,15 @@ static void tch_wait_for_message_request_from_pe_run(const int port) { /* Make sure buffer doesn't overflow */ if (emsg[port].len > BUFFER_SIZE) { - /* Report Error To Policy Engine */ - pe_report_error(port, ERR_TCH_XMIT); - tch_clear_abort_set_chunking(port); + tch[port].error = ERR_TCH_XMIT; + set_state_tch(port, TCH_REPORT_ERROR); return; } + /* NOTE: TCH_Pass_Down_Message embedded here */ /* Copy message to chunked buffer */ memset((uint8_t *)pdmsg[port].chk_buf, - 0, BUFFER_SIZE); + 0, BUFFER_SIZE); memcpy((uint8_t *)pdmsg[port].chk_buf, (uint8_t *)emsg[port].buf, emsg[port].len); @@ -1280,18 +1286,15 @@ static void tch_wait_for_transmission_complete_run(const int port) */ if (PDMSG_CHK_FLAG(port, PRL_FLAGS_TX_COMPLETE)) { PDMSG_CLR_FLAG(port, PRL_FLAGS_TX_COMPLETE); - /* Tell PE message was sent */ - pe_message_sent(port); - set_state_tch(port, TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE); + set_state_tch(port, TCH_MESSAGE_SENT); } /* * Inform Policy Engine of Tx Error */ else if (PDMSG_CHK_FLAG(port, PRL_FLAGS_TX_ERROR)) { PDMSG_CLR_FLAG(port, PRL_FLAGS_TX_ERROR); - /* Tell PE an error occurred */ - pe_report_error(port, ERR_TCH_XMIT); - set_state_tch(port, TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE); + tch[port].error = ERR_TCH_XMIT; + set_state_tch(port, TCH_REPORT_ERROR); } } @@ -1363,18 +1366,15 @@ static void tch_sending_chunked_message_run(const int port) * Transmission Error */ if (PDMSG_CHK_FLAG(port, PRL_FLAGS_TX_ERROR)) { - pe_report_error(port, ERR_TCH_XMIT); - set_state_tch(port, TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE); + tch[port].error = ERR_TCH_XMIT; + set_state_tch(port, TCH_REPORT_ERROR); } /* * Message Transmitted from Protocol Layer & * Last Chunk */ else if (emsg[port].len == pdmsg[port].send_offset) { - set_state_tch(port, TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE); - - /* Tell PE message was sent */ - pe_message_sent(port); + set_state_tch(port, TCH_MESSAGE_SENT); } /* * Any message received and not in state TCH_Wait_Chunk_Request @@ -1427,9 +1427,8 @@ static void tch_wait_chunk_request_run(const int port) * Chunk Number != Chunk Number to Send */ else { - pe_report_error(port, ERR_TCH_CHUNKED); - set_state_tch(port, - TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE); + tch[port].error = ERR_TCH_CHUNKED; + set_state_tch(port, TCH_REPORT_ERROR); } return; } @@ -1445,10 +1444,7 @@ static void tch_wait_chunk_request_run(const int port) */ else if (get_time().val >= tch[port].chunk_sender_request_timer) { - set_state_tch(port, TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE); - - /* Tell PE message was sent */ - pe_message_sent(port); + set_state_tch(port, TCH_MESSAGE_SENT); } } @@ -1466,6 +1462,26 @@ static void tch_message_received_run(const int port) set_state_tch(port, TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE); } +/* + * TchMessageSent + */ +static void tch_message_sent_entry(const int port) +{ + /* Tell PE message was sent */ + pe_message_sent(port); + set_state_tch(port, TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE); +} + +/* + * TchReportError + */ +static void tch_report_error_entry(const int port) +{ + /* Report Error To Policy Engine */ + pe_report_error(port, tch[port].error); + set_state_tch(port, TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE); +} + /* * Protocol Layer Message Reception State Machine */ @@ -1684,6 +1700,12 @@ static const struct usb_state tch_states[] = { .entry = tch_message_received_entry, .run = tch_message_received_run, }, + [TCH_MESSAGE_SENT] = { + .entry = tch_message_sent_entry, + }, + [TCH_REPORT_ERROR] = { + .entry = tch_report_error_entry, + }, }; #ifdef TEST_BUILD diff --git a/test/usb_prl.c b/test/usb_prl.c index 0bbcb1412d..d1cbaf5a94 100644 --- a/test/usb_prl.c +++ b/test/usb_prl.c @@ -61,6 +61,8 @@ enum usb_tch_state { TCH_SENDING_CHUNKED_MESSAGE, TCH_WAIT_CHUNK_REQUEST, TCH_MESSAGE_RECEIVED, + TCH_MESSAGE_SENT, + TCH_REPORT_ERROR, }; /* Defined in implementation */ -- cgit v1.2.1