diff options
author | Abe Levkoy <alevkoy@chromium.org> | 2020-07-23 20:30:53 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-07-24 21:11:25 +0000 |
commit | 8298b19bb8e5708e879615de9cc28e86b954593f (patch) | |
tree | f5d25e764d4847114db5a8f883c377f2c24540d7 | |
parent | 639e946785ff12f5c77fcc66880bbd998bc1d460 (diff) | |
download | chrome-ec-8298b19bb8e5708e879615de9cc28e86b954593f.tar.gz |
TCPMv2: Parse VDM responses in child states
Moving parsing into the parent state PE_VDM_SEND_REQUEST was a code-size
optimization that didn't save very much flash space, and it somewhat
increased complexity. Move the parsing logic back into the child states
for the individual VDMs. Leave parsing logic in common code and
retain the switching structure of the child-state run functions.
Reduce flash size by 60 bytes on average.
(volteer RO: 64; volteer RW: 56)
BUG=b:158572770
TEST=Observe port partner and cable discovery and mode entry
BRANCH=none
Signed-off-by: Abe Levkoy <alevkoy@chromium.org>
Change-Id: I2157a2308ccfb73763661e088c90c5a52a8013b7
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2317053
Reviewed-by: Jett Rink <jettrink@chromium.org>
-rw-r--r-- | common/usbc/usb_pe_drp_sm.c | 108 |
1 files changed, 44 insertions, 64 deletions
diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c index 8b49030983..e028fd75c4 100644 --- a/common/usbc/usb_pe_drp_sm.c +++ b/common/usbc/usb_pe_drp_sm.c @@ -483,9 +483,6 @@ static struct policy_engine { uint32_t vdm_cnt; uint32_t vdm_data[VDO_HDR_SIZE + VDO_MAX_SIZE]; uint8_t vdm_ack_min_data_objects; - enum vdm_response_result vdm_result; - uint32_t vdm_rsp_hdr; - uint32_t vdm_rsp_body[VDO_MAX_SIZE]; /* Timers */ @@ -4094,24 +4091,26 @@ static void pe_handle_custom_vdm_request_exit(int port) static enum vdm_response_result parse_vdm_response_common(int port) { /* Retrieve the message information */ - uint32_t *payload = (uint32_t *)rx_emsg[port].buf; - int sop = PD_HEADER_GET_SOP(rx_emsg[port].header); - uint8_t type = PD_HEADER_TYPE(rx_emsg[port].header); - uint8_t cnt = PD_HEADER_CNT(rx_emsg[port].header); - uint8_t ext = PD_HEADER_EXT(rx_emsg[port].header); + uint32_t *payload; + int sop; + uint8_t type; + uint8_t cnt; + uint8_t ext; + + if (!PE_CHK_FLAG(port, PE_FLAGS_MSG_RECEIVED)) + return VDM_RESULT_WAITING; + + payload = (uint32_t *)rx_emsg[port].buf; + sop = PD_HEADER_GET_SOP(rx_emsg[port].header); + type = PD_HEADER_TYPE(rx_emsg[port].header); + cnt = PD_HEADER_CNT(rx_emsg[port].header); + ext = PD_HEADER_EXT(rx_emsg[port].header); if (sop == pe[port].tx_type && type == PD_DATA_VENDOR_DEF && cnt >= 1 && ext == 0) { if (PD_VDO_CMDT(payload[0]) == CMDT_RSP_ACK && cnt >= pe[port].vdm_ack_min_data_objects) { - /* - * Handle ACKs in state-specific code. The PRL may - * overwrite rx_emsg before the child handles the ACK, - * so save the response in the PE. - */ - pe[port].vdm_rsp_hdr = rx_emsg[port].header; - memcpy(pe[port].vdm_rsp_body, rx_emsg[port].buf, - cnt * sizeof(pe[port].vdm_rsp_body[0])); + /* Handle ACKs in state-specific code. */ return VDM_RESULT_ACK; } else if (PD_VDO_CMDT(payload[0]) == CMDT_RSP_NAK) { /* Handle NAKs in state-specific code. */ @@ -4126,9 +4125,6 @@ static enum vdm_response_result parse_vdm_response_common(int port) pe[port].discover_identity_timer = get_time().val + PD_T_VDM_BUSY; - pe[port].vdm_rsp_hdr = rx_emsg[port].header; - memcpy(pe[port].vdm_rsp_body, rx_emsg[port].buf, - cnt * sizeof(pe[port].vdm_rsp_body[0])); return VDM_RESULT_NO_ACTION; } @@ -4149,9 +4145,6 @@ static enum vdm_response_result parse_vdm_response_common(int port) } /* Unexpected Message Received. Src.Ready or Snk.Ready can handle it. */ - pe[port].vdm_rsp_hdr = rx_emsg[port].header; - memcpy(pe[port].vdm_rsp_body, rx_emsg[port].buf, - cnt * sizeof(pe[port].vdm_rsp_body[0])); PE_SET_FLAG(port, PE_FLAGS_MSG_RECEIVED); return VDM_RESULT_NO_ACTION; } @@ -4177,7 +4170,6 @@ static void pe_vdm_send_request_entry(int port) PE_FLAGS_INTERRUPTIBLE_AMS); pe[port].vdm_response_timer = TIMER_DISABLED; - pe[port].vdm_result = VDM_RESULT_WAITING; } static void pe_vdm_send_request_run(int port) @@ -4202,18 +4194,6 @@ static void pe_vdm_send_request_run(int port) return; } - /* Parse received message. */ - if (PE_CHK_FLAG(port, PE_FLAGS_MSG_RECEIVED)) { - PE_CLR_FLAG(port, PE_FLAGS_MSG_RECEIVED); - pe[port].vdm_result = parse_vdm_response_common(port); - /* - * The child state will handle the received message. Don't wait - * until the next PD task loop iteration to do this. - */ - task_wake(PD_PORT_TO_TASK_ID(port)); - return; - } - /* * Check the VDM timer, child will be responsible for processing * messages and reacting appropriately to unexpected messages. @@ -4275,17 +4255,17 @@ static void pe_vdm_identity_request_cbl_entry(int port) static void pe_vdm_identity_request_cbl_run(int port) { /* Retrieve the message information */ - uint32_t *payload = pe[port].vdm_rsp_body; - int sop = PD_HEADER_GET_SOP(pe[port].vdm_rsp_hdr); - uint8_t type = PD_HEADER_TYPE(pe[port].vdm_rsp_hdr); - uint8_t cnt = PD_HEADER_CNT(pe[port].vdm_rsp_hdr); - uint8_t ext = PD_HEADER_EXT(pe[port].vdm_rsp_hdr); + uint32_t *payload = (uint32_t *) rx_emsg[port].buf; + int sop = PD_HEADER_GET_SOP(rx_emsg[port].header); + uint8_t type = PD_HEADER_TYPE(rx_emsg[port].header); + uint8_t cnt = PD_HEADER_CNT(rx_emsg[port].header); + uint8_t ext = PD_HEADER_EXT(rx_emsg[port].header); - switch (pe[port].vdm_result) { + switch (parse_vdm_response_common(port)) { case VDM_RESULT_WAITING: /* - * The parent didn't parse a message. Handle protocol errors; - * otherwise, continue waiting. + * The common code didn't parse a message. Handle protocol + * errors; otherwise, continue waiting. */ if (PE_CHK_FLAG(port, PE_FLAGS_PROTOCOL_ERROR)) { /* @@ -4333,7 +4313,7 @@ static void pe_vdm_identity_request_cbl_run(int port) */ if (prl_get_rev(port, TCPC_TX_SOP) != PD_REV20) prl_set_rev(port, sop, - PD_HEADER_REV(pe[port].vdm_rsp_hdr)); + PD_HEADER_REV(rx_emsg[port].header)); break; case VDM_RESULT_NAK: /* PE_INIT_PORT_VDM_IDENTITY_NAKed embedded here */ @@ -4398,9 +4378,9 @@ static void pe_init_port_vdm_identity_request_entry(int port) static void pe_init_port_vdm_identity_request_run(int port) { - switch (pe[port].vdm_result) { + switch (parse_vdm_response_common(port)) { case VDM_RESULT_WAITING: - /* If the parent didn't parse a message, continue waiting. */ + /* If common code didn't parse a message, continue waiting. */ return; case VDM_RESULT_NO_ACTION: /* @@ -4411,9 +4391,9 @@ static void pe_init_port_vdm_identity_request_run(int port) break; case VDM_RESULT_ACK: { /* Retrieve the message information. */ - uint32_t *payload = pe[port].vdm_rsp_body; - int sop = PD_HEADER_GET_SOP(pe[port].vdm_rsp_hdr); - uint8_t cnt = PD_HEADER_CNT(pe[port].vdm_rsp_hdr); + uint32_t *payload = (uint32_t *) rx_emsg[port].buf; + int sop = PD_HEADER_GET_SOP(rx_emsg[port].header); + uint8_t cnt = PD_HEADER_CNT(rx_emsg[port].header); /* PE_INIT_PORT_VDM_Identity_ACKed embedded here */ dfp_consume_identity(port, sop, cnt, payload); @@ -4477,9 +4457,9 @@ static void pe_init_vdm_svids_request_entry(int port) static void pe_init_vdm_svids_request_run(int port) { - switch (pe[port].vdm_result) { + switch (parse_vdm_response_common(port)) { case VDM_RESULT_WAITING: - /* If the parent didn't parse a message, continue waiting. */ + /* If common code didn't parse a message, continue waiting. */ return; case VDM_RESULT_NO_ACTION: /* @@ -4490,9 +4470,9 @@ static void pe_init_vdm_svids_request_run(int port) break; case VDM_RESULT_ACK: { /* Retrieve the message information. */ - uint32_t *payload = pe[port].vdm_rsp_body; - int sop = PD_HEADER_GET_SOP(pe[port].vdm_rsp_hdr); - uint8_t cnt = PD_HEADER_CNT(pe[port].vdm_rsp_hdr); + uint32_t *payload = (uint32_t *) rx_emsg[port].buf; + int sop = PD_HEADER_GET_SOP(rx_emsg[port].header); + uint8_t cnt = PD_HEADER_CNT(rx_emsg[port].header); /* PE_INIT_VDM_SVIDs_ACKed embedded here */ dfp_consume_svids(port, sop, cnt, payload); @@ -4554,9 +4534,9 @@ static void pe_init_vdm_modes_request_run(int port) assert(mode_data->discovery == PD_DISC_NEEDED); requested_svid = mode_data->svid; - switch (pe[port].vdm_result) { + switch (parse_vdm_response_common(port)) { case VDM_RESULT_WAITING: - /* If the parent didn't parse a message, continue waiting. */ + /* If common code didn't parse a message, continue waiting. */ return; case VDM_RESULT_NO_ACTION: /* @@ -4567,9 +4547,9 @@ static void pe_init_vdm_modes_request_run(int port) break; case VDM_RESULT_ACK: { /* Retrieve the message information. */ - uint32_t *payload = pe[port].vdm_rsp_body; - int sop = PD_HEADER_GET_SOP(pe[port].vdm_rsp_hdr); - uint8_t cnt = PD_HEADER_CNT(pe[port].vdm_rsp_hdr); + uint32_t *payload = (uint32_t *) rx_emsg[port].buf; + int sop = PD_HEADER_GET_SOP(rx_emsg[port].header); + uint8_t cnt = PD_HEADER_CNT(rx_emsg[port].header); /* PE_INIT_VDM_Modes_ACKed embedded here */ dfp_consume_modes(port, sop, cnt, payload); @@ -4624,9 +4604,9 @@ static void pe_vdm_request_dpm_entry(int port) static void pe_vdm_request_dpm_run(int port) { - switch (pe[port].vdm_result) { + switch (parse_vdm_response_common(port)) { case VDM_RESULT_WAITING: - /* If the parent didn't parse a message, continue waiting. */ + /* If common code didn't parse a message, continue waiting. */ return; case VDM_RESULT_NO_ACTION: /* @@ -4637,9 +4617,9 @@ static void pe_vdm_request_dpm_run(int port) break; case VDM_RESULT_ACK: { /* Retrieve the message information. */ - uint32_t *payload = pe[port].vdm_rsp_body; - int sop = PD_HEADER_GET_SOP(pe[port].vdm_rsp_hdr); - uint8_t cnt = PD_HEADER_CNT(pe[port].vdm_rsp_hdr); + uint32_t *payload = (uint32_t *) rx_emsg[port].buf; + int sop = PD_HEADER_GET_SOP(rx_emsg[port].header); + uint8_t cnt = PD_HEADER_CNT(rx_emsg[port].header); uint16_t svid = PD_VDO_VID(payload[0]); uint8_t vdm_cmd = PD_VDO_CMD(payload[0]); |