diff options
-rw-r--r-- | common/usbc/usb_pe_drp_sm.c | 229 | ||||
-rw-r--r-- | common/usbc/usb_prl_sm.c | 84 | ||||
-rw-r--r-- | include/config.h | 14 | ||||
-rw-r--r-- | include/usb_pd.h | 89 | ||||
-rw-r--r-- | include/usb_prl_sm.h | 5 | ||||
-rw-r--r-- | test/build.mk | 8 | ||||
-rw-r--r-- | test/fake_prl.c | 5 | ||||
-rw-r--r-- | test/test_config.h | 17 | ||||
-rw-r--r-- | test/usb_pe.h | 10 | ||||
-rw-r--r-- | test/usb_pe_drp.c | 127 | ||||
l--------- | test/usb_pe_drp_noextended.c | 1 | ||||
l--------- | test/usb_pe_drp_noextended.tasklist | 1 | ||||
l--------- | test/usb_prl_noextended.c | 1 | ||||
l--------- | test/usb_prl_noextended.tasklist | 1 | ||||
-rw-r--r-- | test/usb_prl_old.c | 59 |
15 files changed, 479 insertions, 172 deletions
diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c index eb1de8ec6b..4c662278c6 100644 --- a/common/usbc/usb_pe_drp_sm.c +++ b/common/usbc/usb_pe_drp_sm.c @@ -255,13 +255,18 @@ enum usb_pe_state { /* AMS Start parent - runs SenderResponseTimer */ PE_SENDER_RESPONSE, +#ifdef CONFIG_USB_PD_REV30 /* PD3.0 only states below here*/ PE_FRS_SNK_SRC_START_AMS, +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES PE_GIVE_BATTERY_CAP, PE_GIVE_BATTERY_STATUS, PE_SEND_ALERT, +#else + PE_SRC_CHUNK_RECEIVED, + PE_SNK_CHUNK_RECEIVED, +#endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */ -#ifdef CONFIG_USB_PD_REV30 /* Super States */ PE_PRS_FRS_SHARED, #endif /* CONFIG_USB_PD_REV30 */ @@ -373,9 +378,14 @@ static const char * const pe_state_names[] = { /* PD3.0 only states below here*/ #ifdef CONFIG_USB_PD_REV30 [PE_FRS_SNK_SRC_START_AMS] = "PE_FRS_SNK_SRC_Start_Ams", +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES [PE_GIVE_BATTERY_CAP] = "PE_Give_Battery_Cap", [PE_GIVE_BATTERY_STATUS] = "PE_Give_Battery_Status", [PE_SEND_ALERT] = "PE_Send_Alert", +#else + [PE_SRC_CHUNK_RECEIVED] = "PE_SRC_Chunk_Received", + [PE_SNK_CHUNK_RECEIVED] = "PE_SNK_Chunk_Received", +#endif /* Super States */ [PE_PRS_FRS_SHARED] = "SS:PE_PRS_FRS_SHARED", @@ -389,6 +399,10 @@ static const char * const pe_state_names[] = { extern const char **pe_state_names; #endif +/* + * Ensure that invalid states don't link properly. This lets us use guard code + * with IS_ENABLED instead of ifdefs and still save flash space. + */ #ifndef CONFIG_USBC_VCONN enum usb_pe_state PE_VCS_EVALUATE_SWAP_NOT_SUPPORTED; enum usb_pe_state PE_VCS_SEND_SWAP_NOT_SUPPORTED; @@ -404,22 +418,42 @@ enum usb_pe_state PE_VCS_SEND_PS_RDY_SWAP_NOT_SUPPORTED; #define PE_VCS_SEND_PS_RDY_SWAP PE_VCS_SEND_PS_RDY_SWAP_NOT_SUPPORTED #endif /* CONFIG_USBC_VCONN */ -/* - * Ensure that Invalid states don't link properly. This let's us use guard - * code with IS_ENABLED instead of ifdefs and still save flash space - */ #ifndef CONFIG_USB_PD_REV30 extern enum usb_pe_state PE_FRS_SNK_SRC_START_AMS_NOT_SUPPORTED; -extern enum usb_pe_state PE_GIVE_BATTERY_CAP_NOT_SUPPORTED; -extern enum usb_pe_state PE_GIVE_BATTERY_STATUS_NOT_SUPPORTED; extern enum usb_pe_state PE_PRS_FRS_SHARE_NOT_SUPPORTED; +STATIC_IF(CONFIG_USB_PD_REV30) + enum usb_pe_state PE_SRC_CHUNK_RECEIVED_NOT_SUPPORTED; +STATIC_IF(CONFIG_USB_PD_REV30) + enum usb_pe_state PE_SNK_CHUNK_RECEIVED_NOT_SUPPORTED; #define PE_FRS_SNK_SRC_START_AMS PE_FRS_SNK_SRC_START_AMS_NOT_SUPPORTED -#define PE_GIVE_BATTERY_CAP PE_GIVE_BATTERY_CAP_NOT_SUPPORTED -#define PE_GIVE_BATTERY_STATUS PE_GIVE_BATTERY_STATUS_NOT_SUPPORTED #define PE_PRS_FRS_SHARED PE_PRS_FRS_SHARED_NOT_SUPPORTED +#define PE_SRC_CHUNK_RECEIVED PE_SRC_CHUNK_RECEIVED_NOT_SUPPORTED +#define PE_SNK_CHUNK_RECEIVED PE_SNK_CHUNK_RECEIVED_NOT_SUPPORTED void pe_set_frs_enable(int port, int enable); #endif /* CONFIG_USB_PD_REV30 */ +#ifndef CONFIG_USB_PD_EXTENDED_MESSAGES +/* Use STATIC_IF instead of bare extern to avoid checkpatch.pl error. */ +STATIC_IF(CONFIG_USB_PD_EXTENDED_MESSAGES) + enum usb_pe_state PE_GIVE_BATTERY_CAP_NOT_SUPPORTED; +STATIC_IF(CONFIG_USB_PD_EXTENDED_MESSAGES) + enum usb_pe_state PE_GIVE_BATTERY_STATUS_NOT_SUPPORTED; +STATIC_IF(CONFIG_USB_PD_EXTENDED_MESSAGES) + enum usb_pe_state PE_SEND_ALERT_NOT_SUPPORTED; +#define PE_GIVE_BATTERY_CAP PE_GIVE_BATTERY_CAP_NOT_SUPPORTED +#define PE_GIVE_BATTERY_STATUS PE_GIVE_BATTERY_STATUS_NOT_SUPPORTED +#define PE_SEND_ALERT PE_SEND_ALERT_NOT_SUPPORTED +#endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */ + +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES +STATIC_IF_NOT(CONFIG_USB_PD_EXTENDED_MESSAGES) + enum usb_pe_state PE_SRC_CHUNK_RECEIVED_NOT_SUPPORTED; +STATIC_IF_NOT(CONFIG_USB_PD_EXTENDED_MESSAGES) + enum usb_pe_state PE_SNK_CHUNK_RECEIVED_NOT_SUPPORTED; +#define PE_SRC_CHUNK_RECEIVED PE_SRC_CHUNK_RECEIVED_NOT_SUPPORTED +#define PE_SNK_CHUNK_RECEIVED PE_SNK_CHUNK_RECEIVED_NOT_SUPPORTED +#endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */ + /* * This enum is used to implement a state machine consisting of at most * 3 states, inside a Policy Engine State. @@ -584,6 +618,17 @@ static struct policy_engine { */ uint64_t wait_and_add_jitter_timer; + /* + * PD 3.0, version 2.0, section 6.6.18.1: The ChunkingNotSupportedTimer + * is used by a Source or Sink which does not support multi-chunk + * Chunking but has received a Message Chunk. The + * ChunkingNotSupportedTimer Shall be started when the last bit of the + * EOP of a Message Chunk of a multi-chunk Message is received. The + * Policy Engine Shall Not send its Not_Supported Message before the + * ChunkingNotSupportedTimer expires. + */ + uint64_t chunking_not_supported_timer; + /* Counters */ /* @@ -1103,7 +1148,7 @@ test_export_static enum usb_pe_state get_state_pe(const int port) static bool common_src_snk_dpm_requests(int port) { - if (IS_ENABLED(CONFIG_USB_PD_REV30) && + if (IS_ENABLED(CONFIG_USB_PD_EXTENDED_MESSAGES) && PE_CHK_DPM_REQUEST(port, DPM_REQUEST_SEND_ALERT)) { PE_CLR_DPM_REQUEST(port, DPM_REQUEST_SEND_ALERT); set_state_pe(port, PE_SEND_ALERT); @@ -1885,6 +1930,28 @@ static void pe_src_transition_supply_run(int port) } } +/* + * Transitions state after receiving a Not Supported extended message. Under + * appropriate conditions, transitions to a PE_{SRC,SNK}_Chunk_Received. + */ +static void extended_message_not_supported(int port, uint32_t *payload) +{ + uint16_t ext_header = GET_EXT_HEADER(*payload); + + if (IS_ENABLED(CONFIG_USB_PD_REV30) && + !IS_ENABLED(CONFIG_USB_PD_EXTENDED_MESSAGES) && + PD_EXT_HEADER_CHUNKED(ext_header) && + PD_EXT_HEADER_DATA_SIZE(ext_header) > + PD_MAX_EXTENDED_MESSAGE_CHUNK_LEN) { + set_state_pe(port, + pe[port].power_role == PD_ROLE_SOURCE ? + PE_SRC_CHUNK_RECEIVED : PE_SNK_CHUNK_RECEIVED); + return; + } + + set_state_pe(port, PE_SEND_NOT_SUPPORTED); +} + /** * PE_SRC_Ready */ @@ -1904,11 +1971,6 @@ static void pe_src_ready_entry(int port) static void pe_src_ready_run(int port) { - uint32_t payload; - uint8_t type; - uint8_t cnt; - uint8_t ext; - /* * Don't delay handling a hard reset from the device policy manager. */ @@ -1923,26 +1985,26 @@ static void pe_src_ready_run(int port) * reset */ if (PE_CHK_FLAG(port, PE_FLAGS_MSG_RECEIVED)) { - PE_CLR_FLAG(port, PE_FLAGS_MSG_RECEIVED); + 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 = (uint32_t *)rx_emsg[port].buf; - type = PD_HEADER_TYPE(rx_emsg[port].header); - cnt = PD_HEADER_CNT(rx_emsg[port].header); - ext = PD_HEADER_EXT(rx_emsg[port].header); - payload = *(uint32_t *)rx_emsg[port].buf; + PE_CLR_FLAG(port, PE_FLAGS_MSG_RECEIVED); /* Extended Message Requests */ if (ext > 0) { switch (type) { -#if defined(CONFIG_USB_PD_REV30) && defined(CONFIG_BATTERY) +#if defined(CONFIG_USB_PD_EXTENDED_MESSAGES) && defined(CONFIG_BATTERY) case PD_EXT_GET_BATTERY_CAP: set_state_pe(port, PE_GIVE_BATTERY_CAP); break; case PD_EXT_GET_BATTERY_STATUS: set_state_pe(port, PE_GIVE_BATTERY_STATUS); break; -#endif /* CONFIG_USB_PD_REV30 && CONFIG_BATTERY*/ +#endif /* CONFIG_USB_PD_EXTENDED_MESSAGES && CONFIG_BATTERY*/ default: - set_state_pe(port, PE_SEND_NOT_SUPPORTED); + extended_message_not_supported(port, payload); } return; } @@ -1957,7 +2019,7 @@ static void pe_src_ready_run(int port) case PD_DATA_VENDOR_DEF: if (PD_HEADER_TYPE(rx_emsg[port].header) == PD_DATA_VENDOR_DEF) { - if (PD_VDO_SVDM(payload)) { + if (PD_VDO_SVDM(*payload)) { set_state_pe(port, PE_VDM_RESPONSE); } else @@ -2639,11 +2701,6 @@ static void pe_snk_ready_entry(int port) static void pe_snk_ready_run(int port) { - uint32_t payload; - uint8_t type; - uint8_t cnt; - uint8_t ext; - /* * Don't delay handling a hard reset from the device policy manager. */ @@ -2658,26 +2715,26 @@ static void pe_snk_ready_run(int port) * reset */ if (PE_CHK_FLAG(port, PE_FLAGS_MSG_RECEIVED)) { - PE_CLR_FLAG(port, PE_FLAGS_MSG_RECEIVED); + 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 = (uint32_t *)rx_emsg[port].buf; - type = PD_HEADER_TYPE(rx_emsg[port].header); - cnt = PD_HEADER_CNT(rx_emsg[port].header); - ext = PD_HEADER_EXT(rx_emsg[port].header); - payload = *(uint32_t *)rx_emsg[port].buf; + PE_CLR_FLAG(port, PE_FLAGS_MSG_RECEIVED); /* Extended Message Request */ if (ext > 0) { switch (type) { -#if defined(CONFIG_USB_PD_REV30) && defined(CONFIG_BATTERY) +#if defined(CONFIG_USB_PD_EXTENDED_MESSAGES) && defined(CONFIG_BATTERY) case PD_EXT_GET_BATTERY_CAP: set_state_pe(port, PE_GIVE_BATTERY_CAP); break; case PD_EXT_GET_BATTERY_STATUS: set_state_pe(port, PE_GIVE_BATTERY_STATUS); break; -#endif /* CONFIG_USB_PD_REV30 && CONFIG_BATTERY */ +#endif /* CONFIG_USB_PD_EXTENDED_MESSAGES && CONFIG_BATTERY */ default: - set_state_pe(port, PE_SEND_NOT_SUPPORTED); + extended_message_not_supported(port, payload); } return; } @@ -2691,7 +2748,7 @@ static void pe_snk_ready_run(int port) case PD_DATA_VENDOR_DEF: if (PD_HEADER_TYPE(rx_emsg[port].header) == PD_DATA_VENDOR_DEF) { - if (PD_VDO_SVDM(payload)) + if (PD_VDO_SVDM(*payload)) set_state_pe(port, PE_VDM_RESPONSE); else @@ -3067,6 +3124,35 @@ static void pe_send_not_supported_run(int port) } } +#if defined(CONFIG_USB_PD_REV30) && !defined(CONFIG_USB_PD_EXTENDED_MESSAGES) +/** + * PE_SRC_Chunk_Received and PE_SNK_Chunk_Received + * + * 6.11.2.1.1 Architecture of Device Including Chunking Layer (Revision 3.0, + * Version 2.0): If a PD Device or Cable Marker has no requirement to handle any + * message requiring more than one Chunk of any Extended Message, it May omit + * the Chunking Layer. In this case it Shall implement the + * ChunkingNotSupportedTimer to ensure compatible operation with partners which + * support Chunking. + * + * See also: + * 6.6.18.1 ChunkingNotSupportedTimer + * 8.3.3.6 Not Supported Message State Diagrams + */ +static void pe_chunk_received_entry(int port) +{ + print_current_state(port); + pe[port].chunking_not_supported_timer = + get_time().val + PD_T_CHUNKING_NOT_SUPPORTED; +} + +static void pe_chunk_received_run(int port) +{ + if (get_time().val > pe[port].chunking_not_supported_timer) + set_state_pe(port, PE_SEND_NOT_SUPPORTED); +} +#endif + /** * PE_SRC_Ping */ @@ -3084,7 +3170,7 @@ static void pe_src_ping_run(int port) } } -#ifdef CONFIG_USB_PD_REV30 +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES /** * PE_Give_Battery_Cap */ @@ -3275,7 +3361,7 @@ static void pe_send_alert_run(int port) pe_set_ready_state(port); } } -#endif /* CONFIG_USB_PD_REV30 */ +#endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */ /** * PE_DRS_Evaluate_Swap @@ -5412,14 +5498,6 @@ uint32_t pe_get_flags(int port) static const struct usb_state pe_states[] = { - /* Super States */ -#ifdef CONFIG_USB_PD_REV30 - [PE_PRS_FRS_SHARED] = { - .entry = pe_prs_frs_shared_entry, - .exit = pe_prs_frs_shared_exit, - }, -#endif /* CONFIG_USB_PD_REV30 */ - /* Normal States */ [PE_SRC_STARTUP] = { .entry = pe_src_startup_entry, @@ -5523,20 +5601,6 @@ static const struct usb_state pe_states[] = { .entry = pe_src_ping_entry, .run = pe_src_ping_run, }, -#ifdef CONFIG_USB_PD_REV30 - [PE_GIVE_BATTERY_CAP] = { - .entry = pe_give_battery_cap_entry, - .run = pe_give_battery_cap_run, - }, - [PE_GIVE_BATTERY_STATUS] = { - .entry = pe_give_battery_status_entry, - .run = pe_give_battery_status_run, - }, - [PE_SEND_ALERT] = { - .entry = pe_send_alert_entry, - .run = pe_send_alert_run, - }, -#endif /* CONFIG_USB_PD_REV30 */ [PE_DRS_EVALUATE_SWAP] = { .entry = pe_drs_evaluate_swap_entry, .run = pe_drs_evaluate_swap_run, @@ -5613,12 +5677,6 @@ static const struct usb_state pe_states[] = { .parent = &pe_states[PE_PRS_FRS_SHARED], #endif /* CONFIG_USB_PD_REV30 */ }, -#ifdef CONFIG_USB_PD_REV30 - [PE_FRS_SNK_SRC_START_AMS] = { - .entry = pe_frs_snk_src_start_ams_entry, - .parent = &pe_states[PE_PRS_FRS_SHARED], - }, -#endif /* CONFIG_USB_PD_REV30 */ #ifdef CONFIG_USBC_VCONN [PE_VCS_EVALUATE_SWAP] = { .entry = pe_vcs_evaluate_swap_entry, @@ -5714,6 +5772,41 @@ static const struct usb_state pe_states[] = { .entry = pe_sender_response_entry, .run = pe_sender_response_run, }, +#ifdef CONFIG_USB_PD_REV30 + [PE_FRS_SNK_SRC_START_AMS] = { + .entry = pe_frs_snk_src_start_ams_entry, + .parent = &pe_states[PE_PRS_FRS_SHARED], + }, +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES + [PE_GIVE_BATTERY_CAP] = { + .entry = pe_give_battery_cap_entry, + .run = pe_give_battery_cap_run, + }, + [PE_GIVE_BATTERY_STATUS] = { + .entry = pe_give_battery_status_entry, + .run = pe_give_battery_status_run, + }, + [PE_SEND_ALERT] = { + .entry = pe_send_alert_entry, + .run = pe_send_alert_run, + }, +#else + [PE_SRC_CHUNK_RECEIVED] = { + .entry = pe_chunk_received_entry, + .run = pe_chunk_received_run, + }, + [PE_SNK_CHUNK_RECEIVED] = { + .entry = pe_chunk_received_entry, + .run = pe_chunk_received_run, + }, +#endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */ + + /* Super States */ + [PE_PRS_FRS_SHARED] = { + .entry = pe_prs_frs_shared_entry, + .exit = pe_prs_frs_shared_exit, + }, +#endif /* CONFIG_USB_PD_REV30 */ }; #ifdef TEST_BUILD diff --git a/common/usbc/usb_prl_sm.c b/common/usbc/usb_prl_sm.c index 4fa01ad1dc..179481a774 100644 --- a/common/usbc/usb_prl_sm.c +++ b/common/usbc/usb_prl_sm.c @@ -181,7 +181,7 @@ static const char * const prl_hr_state_names[] = { = "PRL_HR_WAIT_FOR_PE_HARD_RESET_COMPLETE", }; -#ifdef CONFIG_USB_PD_REV30 +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES static const char * const rch_state_names[] = { [RCH_WAIT_FOR_MESSAGE_FROM_PROTOCOL_LAYER] = "RCH_WAIT_FOR_MESSAGE_FROM_PROTOCOL_LAYER", @@ -204,13 +204,13 @@ static const char * const tch_state_names[] = { [TCH_MESSAGE_SENT] = "TCH_MESSAGE_SENT", [TCH_REPORT_ERROR] = "TCH_REPORT_ERROR", }; -#endif /* CONFIG_USB_PD_REV30 */ +#endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */ /* Forward declare full list of states. Index by above enums. */ static const struct usb_state prl_tx_states[]; static const struct usb_state prl_hr_states[]; -#ifdef CONFIG_USB_PD_REV30 +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES static const struct usb_state rch_states[]; static const struct usb_state tch_states[]; #endif /* CONFIG_USB_PD_REV30 */ @@ -292,7 +292,7 @@ static struct pd_message { uint32_t rx_chk_buf[CHK_BUF_SIZE]; uint32_t chunk_number_expected; uint32_t num_bytes_received; -#ifdef CONFIG_USB_PD_REV30 +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES /* extended message */ uint8_t ext; uint32_t chunk_number_to_send; @@ -397,12 +397,12 @@ static void print_current_prl_hr_state(const int port) /* Set the chunked Rx statemachine to a new state. */ static void set_state_rch(const int port, const enum usb_rch_state new_state) { -#ifdef CONFIG_USB_PD_REV30 +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES set_state(port, &rch[port].ctx, &rch_states[new_state]); #endif /* CONFIG_USB_PD_REV30 */ } -#ifdef CONFIG_USB_PD_REV30 +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES /* Get the chunked Rx statemachine's current state. */ test_export_static enum usb_rch_state rch_get_state(const int port) { @@ -416,12 +416,12 @@ static void print_current_rch_state(const int port) CPRINTS("C%d: %s", port, rch_state_names[rch_get_state(port)]); } -#endif /* CONFIG_USB_PD_REV30 */ +#endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */ /* Set the chunked Tx statemachine to a new state. */ static void set_state_tch(const int port, const enum usb_tch_state new_state) { -#ifdef CONFIG_USB_PD_REV30 +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES set_state(port, &tch[port].ctx, &tch_states[new_state]); #endif /* CONFIG_USB_PD_REV30 */ } @@ -429,14 +429,14 @@ static void set_state_tch(const int port, const enum usb_tch_state new_state) /* Get the chunked Tx statemachine's current state. */ test_export_static enum usb_tch_state tch_get_state(const int port) { -#ifdef CONFIG_USB_PD_REV30 +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES return tch[port].ctx.current - &tch_states[0]; #else return 0; -#endif /* CONFIG_USB_PD_REV30 */ +#endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */ } -#ifdef CONFIG_USB_PD_REV30 +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES /* Print the chunked Tx statemachine's current state. */ static void print_current_tch_state(const int port) { @@ -444,7 +444,7 @@ static void print_current_tch_state(const int port) CPRINTS("C%d: %s", port, tch_state_names[tch_get_state(port)]); } -#endif /* CONFIG_USB_PD_REV30 */ +#endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */ void pd_transmit_complete(int port, int status) { @@ -511,13 +511,13 @@ static void prl_init(int port) prl_tx[port].ctx = cleared; set_state_prl_tx(port, PRL_TX_PHY_LAYER_RESET); -#ifdef CONFIG_USB_PD_REV30 +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES rch[port].ctx = cleared; set_state_rch(port, RCH_WAIT_FOR_MESSAGE_FROM_PROTOCOL_LAYER); tch[port].ctx = cleared; set_state_tch(port, TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE); -#endif /* CONFIG_USB_PD_REV30 */ +#endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */ prl_hr[port].ctx = cleared; set_state_prl_hr(port, PRL_HR_WAIT_FOR_REQUEST); @@ -543,10 +543,10 @@ void prl_send_ctrl_msg(int port, pdmsg[port].xmit_type = type; pdmsg[port].msg_type = msg; pdmsg[port].data_objs = 0; + tx_emsg[port].len = 0; -#ifdef CONFIG_USB_PD_REV30 +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES pdmsg[port].ext = 0; - tx_emsg[port].len = 0; TCH_SET_FLAG(port, PRL_FLAGS_MSG_XMIT); #else @@ -563,7 +563,7 @@ void prl_send_data_msg(int port, pdmsg[port].xmit_type = type; pdmsg[port].msg_type = msg; -#ifdef CONFIG_USB_PD_REV30 +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES pdmsg[port].ext = 0; TCH_SET_FLAG(port, PRL_FLAGS_MSG_XMIT); @@ -575,7 +575,7 @@ void prl_send_data_msg(int port, task_set_event(PD_PORT_TO_TASK_ID(port), PD_EVENT_SM, 0); } -#ifdef CONFIG_USB_PD_REV30 +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES void prl_send_ext_data_msg(int port, enum tcpm_transmit_type type, enum pd_ext_msg_type msg) @@ -587,7 +587,7 @@ void prl_send_ext_data_msg(int port, TCH_SET_FLAG(port, PRL_FLAGS_MSG_XMIT); task_set_event(PD_PORT_TO_TASK_ID(port), PD_EVENT_SM, 0); } -#endif /* CONFIG_USB_PD_REV30 */ +#endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */ static void prl_set_default_pd_revision(int port) { /* @@ -642,7 +642,7 @@ void prl_run(int port, int evt, int en) /* Run Protocol Layer Message Reception */ prl_rx_wait_for_phy_message(port, evt); -#ifdef CONFIG_USB_PD_REV30 +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES /* * Run RX Chunked state machine after prl_rx. This is what * informs the PE of incoming message. Its input is prl_rx @@ -654,19 +654,19 @@ void prl_run(int port, int evt, int en) * to split an extended message and prl_tx can send it for us */ run_state(port, &tch[port].ctx); -#endif /* CONFIG_USB_PD_REV30 */ +#endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */ /* Run Protocol Layer Message Transmission state machine */ run_state(port, &prl_tx[port].ctx); -#ifdef CONFIG_USB_PD_REV30 +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES /* * Run TX Chunked state machine again after prl_tx so we can * handle passing TX_COMPLETE (or failure) up to PE in a single * iteration. */ run_state(port, &tch[port].ctx); -#endif /* CONFIG_USB_PD_REV30 */ +#endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */ /* Run Protocol Layer Hard Reset state machine */ run_state(port, &prl_hr[port].ctx); @@ -938,7 +938,7 @@ static uint32_t get_sop_star_header(const int port) const int is_sop_packet = pdmsg[port].xmit_type == TCPC_TX_SOP; int ext; -#ifdef CONFIG_USB_PD_REV30 +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES ext = pdmsg[port].ext; #else ext = 0; @@ -1011,13 +1011,13 @@ static void prl_tx_wait_for_phy_response_run(const int port) /* Increment check RetryCounter */ prl_tx[port].retry_counter++; -#ifdef CONFIG_USB_PD_REV30 +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES pd3_retry_check = (pdmsg[port].ext && PD_EXT_HEADER_DATA_SIZE(GET_EXT_HEADER( pdmsg[port].tx_chk_buf[0]) > 26)); #else pd3_retry_check = 0; -#endif /* CONFIG_USB_PD_REV30 */ +#endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */ /* * (RetryCounter > nRetryCount) | Large Extended Message @@ -1029,7 +1029,7 @@ static void prl_tx_wait_for_phy_response_run(const int port) * here. */ - if (IS_ENABLED(CONFIG_USB_PD_REV30)) { + if (IS_ENABLED(CONFIG_USB_PD_EXTENDED_MESSAGES)) { /* * State tch_wait_for_transmission_complete will * inform policy engine of error @@ -1058,7 +1058,7 @@ static void prl_tx_wait_for_phy_response_run(const int port) increment_msgid_counter(port); /* Inform Policy Engine Message was sent */ - if (IS_ENABLED(CONFIG_USB_PD_REV30)) + if (IS_ENABLED(CONFIG_USB_PD_EXTENDED_MESSAGES)) PDMSG_SET_FLAG(port, PRL_FLAGS_TX_COMPLETE); else pe_message_sent(port); @@ -1193,10 +1193,10 @@ static void prl_hr_reset_layer_entry(const int port) */ set_state_prl_tx(port, PRL_TX_WAIT_FOR_MESSAGE_REQUEST); -#ifdef CONFIG_USB_PD_REV30 +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES tch[port].flags = 0; rch[port].flags = 0; -#endif /* CONFIG_USB_PD_REV30 */ +#endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */ pdmsg[port].flags = 0; @@ -1290,7 +1290,7 @@ static void prl_hr_wait_for_pe_hard_reset_complete_exit(const int port) /* Exit from Hard Reset */ set_state_prl_tx(port, PRL_TX_PHY_LAYER_RESET); - if (IS_ENABLED(CONFIG_USB_PD_REV30)) { + if (IS_ENABLED(CONFIG_USB_PD_EXTENDED_MESSAGES)) { set_state_rch(port, RCH_WAIT_FOR_MESSAGE_FROM_PROTOCOL_LAYER); set_state_tch(port, TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE); } @@ -1310,7 +1310,7 @@ static void copy_chunk_to_ext(int port) rx_emsg[port].len = pdmsg[port].num_bytes_received; } -#ifdef CONFIG_USB_PD_REV30 +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES /* * Chunked Rx State Machine */ @@ -1953,7 +1953,7 @@ static void tch_report_error_entry(const int port) set_state_tch(port, TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE); } -#endif /* CONFIG_USB_PD_REV30 */ +#endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */ /* * Protocol Layer Message Reception State Machine @@ -1969,7 +1969,7 @@ static void prl_rx_wait_for_phy_message(const int port, int evt) * If PD3, wait for the RX chunk SM to copy the pdmsg into the extended * buffer before overwriting pdmsg. */ - if (IS_ENABLED(CONFIG_USB_PD_REV30) && + if (IS_ENABLED(CONFIG_USB_PD_EXTENDED_MESSAGES) && RCH_CHK_FLAG(port, PRL_FLAGS_MSG_RECEIVED)) return; @@ -2023,7 +2023,7 @@ static void prl_rx_wait_for_phy_message(const int port, int evt) /* Soft Reset occurred */ set_state_prl_tx(port, PRL_TX_PHY_LAYER_RESET); - if (IS_ENABLED(CONFIG_USB_PD_REV30)) { + if (IS_ENABLED(CONFIG_USB_PD_EXTENDED_MESSAGES)) { set_state_rch(port, RCH_WAIT_FOR_MESSAGE_FROM_PROTOCOL_LAYER); set_state_tch(port, @@ -2067,7 +2067,7 @@ static void prl_rx_wait_for_phy_message(const int port, int evt) /* Store Message Id */ prl_rx[port].msg_id[prl_rx[port].sop] = msid; - if (IS_ENABLED(CONFIG_USB_PD_REV30)) { + if (IS_ENABLED(CONFIG_USB_PD_EXTENDED_MESSAGES)) { /* RTR Chunked Message Router States. */ /* * Received Ping from Protocol Layer @@ -2180,7 +2180,7 @@ static const struct usb_state prl_hr_states[] = { }, }; -#ifdef CONFIG_USB_PD_REV30 +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES /* All necessary Chunked Rx states (Section 6.11.2.1.2) */ static const struct usb_state rch_states[] = { [RCH_WAIT_FOR_MESSAGE_FROM_PROTOCOL_LAYER] = { @@ -2241,7 +2241,7 @@ static const struct usb_state tch_states[] = { .entry = tch_report_error_entry, }, }; -#endif +#endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */ #ifdef TEST_BUILD @@ -2258,7 +2258,7 @@ const struct test_sm_data test_prl_sm_data[] = { .names = prl_hr_state_names, .names_size = ARRAY_SIZE(prl_hr_state_names), }, -#ifdef CONFIG_USB_PD_REV30 +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES { .base = rch_states, .size = ARRAY_SIZE(rch_states), @@ -2271,14 +2271,14 @@ const struct test_sm_data test_prl_sm_data[] = { .names = tch_state_names, .names_size = ARRAY_SIZE(tch_state_names), }, -#endif /* CONFIG_USB_PD_REV30 */ +#endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */ }; BUILD_ASSERT(ARRAY_SIZE(prl_tx_states) == ARRAY_SIZE(prl_tx_state_names)); BUILD_ASSERT(ARRAY_SIZE(prl_hr_states) == ARRAY_SIZE(prl_hr_state_names)); -#ifdef CONFIG_USB_PD_REV30 +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES BUILD_ASSERT(ARRAY_SIZE(rch_states) == ARRAY_SIZE(rch_state_names)); BUILD_ASSERT(ARRAY_SIZE(tch_states) == ARRAY_SIZE(tch_state_names)); -#endif /* CONFIG_USB_PD_REV30 */ +#endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */ const int test_prl_sm_data_size = ARRAY_SIZE(test_prl_sm_data); #endif diff --git a/include/config.h b/include/config.h index c94be56206..78fd4b71cf 100644 --- a/include/config.h +++ b/include/config.h @@ -3885,6 +3885,14 @@ */ #undef CONFIG_USB_PD_REV30 +/* + * Support USB PD 3.0 Extended Messages. This will only take effect if + * CONFIG_USB_PD_REV30 is also enabled. Note that Chromebooks disabling this + * config item are non-compliant with PD 3.0, because they have batteries but do + * not support Get_Battery_Cap or Get_Battery_Status. + */ +#define CONFIG_USB_PD_EXTENDED_MESSAGES + /* Major and Minor ChromeOS specific PD device Hardware IDs. */ #undef CONFIG_USB_PD_HW_DEV_ID_BOARD_MAJOR #undef CONFIG_USB_PD_HW_DEV_ID_BOARD_MINOR @@ -4726,7 +4734,11 @@ #define CONFIG_USB_PD_FRS #endif - +/******************************************************************************/ +/* Disable extended message support if PD 3.0 support is disabled. */ +#ifndef CONFIG_USB_PD_REV30 +#undef CONFIG_USB_PD_EXTENDED_MESSAGES +#endif /******************************************************************************/ /* diff --git a/include/usb_pd.h b/include/usb_pd.h index 5d09b7ab6c..e34220da0b 100644 --- a/include/usb_pd.h +++ b/include/usb_pd.h @@ -188,50 +188,51 @@ enum pd_rx_errors { #define SVID_DISCOVERY_MAX 16 /* Timers */ -#define PD_T_SINK_TX (18*MSEC) /* between 16ms and 20 */ -#define PD_T_CHUNK_SENDER_RSP (24*MSEC) /* between 24ms and 30ms */ -#define PD_T_CHUNK_SENDER_REQ (24*MSEC) /* between 24ms and 30ms */ -#define PD_T_HARD_RESET_COMPLETE (5*MSEC) /* between 4ms and 5ms*/ -#define PD_T_HARD_RESET_RETRY (1*MSEC) /* 1ms */ -#define PD_T_SEND_SOURCE_CAP (100*MSEC) /* between 100ms and 200ms */ -#define PD_T_SINK_WAIT_CAP (600*MSEC) /* between 310ms and 620ms */ -#define PD_T_SINK_TRANSITION (35*MSEC) /* between 20ms and 35ms */ -#define PD_T_SOURCE_ACTIVITY (45*MSEC) /* between 40ms and 50ms */ -#define PD_T_SENDER_RESPONSE (30*MSEC) /* between 24ms and 30ms */ -#define PD_T_PS_TRANSITION (500*MSEC) /* between 450ms and 550ms */ -#define PD_T_PS_SOURCE_ON (480*MSEC) /* between 390ms and 480ms */ -#define PD_T_PS_SOURCE_OFF (920*MSEC) /* between 750ms and 920ms */ -#define PD_T_PS_HARD_RESET (25*MSEC) /* between 25ms and 35ms */ -#define PD_T_ERROR_RECOVERY (240*MSEC) /* min 240ms if sourcing VConn */ -#define PD_T_CC_DEBOUNCE (100*MSEC) /* between 100ms and 200ms */ +#define PD_T_SINK_TX (18*MSEC) /* between 16ms and 20 */ +#define PD_T_CHUNKING_NOT_SUPPORTED (45*MSEC) /* between 40ms and 50ms */ +#define PD_T_CHUNK_SENDER_RSP (24*MSEC) /* between 24ms and 30ms */ +#define PD_T_CHUNK_SENDER_REQ (24*MSEC) /* between 24ms and 30ms */ +#define PD_T_HARD_RESET_COMPLETE (5*MSEC) /* between 4ms and 5ms*/ +#define PD_T_HARD_RESET_RETRY (1*MSEC) /* 1ms */ +#define PD_T_SEND_SOURCE_CAP (100*MSEC) /* between 100ms and 200ms */ +#define PD_T_SINK_WAIT_CAP (600*MSEC) /* between 310ms and 620ms */ +#define PD_T_SINK_TRANSITION (35*MSEC) /* between 20ms and 35ms */ +#define PD_T_SOURCE_ACTIVITY (45*MSEC) /* between 40ms and 50ms */ +#define PD_T_SENDER_RESPONSE (30*MSEC) /* between 24ms and 30ms */ +#define PD_T_PS_TRANSITION (500*MSEC) /* between 450ms and 550ms */ +#define PD_T_PS_SOURCE_ON (480*MSEC) /* between 390ms and 480ms */ +#define PD_T_PS_SOURCE_OFF (920*MSEC) /* between 750ms and 920ms */ +#define PD_T_PS_HARD_RESET (25*MSEC) /* between 25ms and 35ms */ +#define PD_T_ERROR_RECOVERY (240*MSEC) /* min 240ms if sourcing VConn */ +#define PD_T_CC_DEBOUNCE (100*MSEC) /* between 100ms and 200ms */ /* DRP_SNK + DRP_SRC must be between 50ms and 100ms with 30%-70% duty cycle */ -#define PD_T_DRP_SNK (40*MSEC) /* toggle time for sink DRP */ -#define PD_T_DRP_SRC (30*MSEC) /* toggle time for source DRP */ -#define PD_T_DEBOUNCE (15*MSEC) /* between 10ms and 20ms */ -#define PD_T_TRY_CC_DEBOUNCE (15*MSEC) /* between 10ms and 20ms */ -#define PD_T_SINK_ADJ (55*MSEC) /* between PD_T_DEBOUNCE and 60ms */ -#define PD_T_SRC_RECOVER (760*MSEC) /* between 660ms and 1000ms */ -#define PD_T_SRC_RECOVER_MAX (1000*MSEC) /* 1000ms */ -#define PD_T_SRC_TURN_ON (275*MSEC) /* 275ms */ -#define PD_T_SAFE_0V (650*MSEC) /* 650ms */ -#define PD_T_NO_RESPONSE (5500*MSEC) /* between 4.5s and 5.5s */ -#define PD_T_BIST_TRANSMIT (50*MSEC) /* 50ms (used for task_wait arg) */ -#define PD_T_BIST_RECEIVE (60*MSEC) /* 60ms (max time to process bist) */ -#define PD_T_BIST_CONT_MODE (60*MSEC) /* 30ms to 60ms */ -#define PD_T_VCONN_SOURCE_ON (100*MSEC) /* 100ms */ -#define PD_T_DRP_TRY (125*MSEC) /* btween 75 and 150ms(monitor Vbus) */ -#define PD_T_TRY_TIMEOUT (550*MSEC) /* between 550ms and 1100ms */ -#define PD_T_TRY_WAIT (600*MSEC) /* Max time for TryWait.SNK state */ -#define PD_T_SINK_REQUEST (100*MSEC) /* Wait 100ms before next request */ -#define PD_T_PD_DEBOUNCE (15*MSEC) /* between 10ms and 20ms */ -#define PD_T_CHUNK_SENDER_RESPONSE (25*MSEC) /* 25ms */ -#define PD_T_CHUNK_SENDER_REQUEST (25*MSEC) /* 25ms */ -#define PD_T_SWAP_SOURCE_START (25*MSEC) /* Min of 20ms */ -#define PD_T_RP_VALUE_CHANGE (20*MSEC) /* 20ms */ -#define PD_T_SRC_DISCONNECT (15*MSEC) /* 15ms */ -#define PD_T_VCONN_STABLE (50*MSEC) /* 50ms */ -#define PD_T_DISCOVER_IDENTITY (45*MSEC) /* between 40ms and 50ms */ -#define PD_T_SYSJUMP (1000*MSEC) /* 1s */ +#define PD_T_DRP_SNK (40*MSEC) /* toggle time for sink DRP */ +#define PD_T_DRP_SRC (30*MSEC) /* toggle time for source DRP */ +#define PD_T_DEBOUNCE (15*MSEC) /* between 10ms and 20ms */ +#define PD_T_TRY_CC_DEBOUNCE (15*MSEC) /* between 10ms and 20ms */ +#define PD_T_SINK_ADJ (55*MSEC) /* between tPDDebounce and 60ms */ +#define PD_T_SRC_RECOVER (760*MSEC) /* between 660ms and 1000ms */ +#define PD_T_SRC_RECOVER_MAX (1000*MSEC) /* 1000ms */ +#define PD_T_SRC_TURN_ON (275*MSEC) /* 275ms */ +#define PD_T_SAFE_0V (650*MSEC) /* 650ms */ +#define PD_T_NO_RESPONSE (5500*MSEC) /* between 4.5s and 5.5s */ +#define PD_T_BIST_TRANSMIT (50*MSEC) /* 50ms (for task_wait arg) */ +#define PD_T_BIST_RECEIVE (60*MSEC) /* 60ms (time to process bist) */ +#define PD_T_BIST_CONT_MODE (60*MSEC) /* 30ms to 60ms */ +#define PD_T_VCONN_SOURCE_ON (100*MSEC) /* 100ms */ +#define PD_T_DRP_TRY (125*MSEC) /* between 75ms and 150ms */ +#define PD_T_TRY_TIMEOUT (550*MSEC) /* between 550ms and 1100ms */ +#define PD_T_TRY_WAIT (600*MSEC) /* Wait time for TryWait.SNK */ +#define PD_T_SINK_REQUEST (100*MSEC) /* 100ms before next request */ +#define PD_T_PD_DEBOUNCE (15*MSEC) /* between 10ms and 20ms */ +#define PD_T_CHUNK_SENDER_RESPONSE (25*MSEC) /* 25ms */ +#define PD_T_CHUNK_SENDER_REQUEST (25*MSEC) /* 25ms */ +#define PD_T_SWAP_SOURCE_START (25*MSEC) /* Min of 20ms */ +#define PD_T_RP_VALUE_CHANGE (20*MSEC) /* 20ms */ +#define PD_T_SRC_DISCONNECT (15*MSEC) /* 15ms */ +#define PD_T_VCONN_STABLE (50*MSEC) /* 50ms */ +#define PD_T_DISCOVER_IDENTITY (45*MSEC) /* between 40ms and 50ms */ +#define PD_T_SYSJUMP (1000*MSEC) /* 1s */ /* number of edges and time window to detect CC line is not idle */ #define PD_RX_TRANSITION_COUNT 3 @@ -1231,6 +1232,8 @@ enum pd_msg_type { /* Used to get extended header from the first 32-bit word of the message */ #define GET_EXT_HEADER(msg) (msg & 0xffff) +#define PD_MAX_EXTENDED_MESSAGE_CHUNK_LEN 26 + /* K-codes for special symbols */ #define PD_SYNC1 0x18 #define PD_SYNC2 0x11 diff --git a/include/usb_prl_sm.h b/include/usb_prl_sm.h index 6b35bd67e8..3575d9443b 100644 --- a/include/usb_prl_sm.h +++ b/include/usb_prl_sm.h @@ -124,6 +124,11 @@ void prl_execute_hard_reset(int port); * Fake to track the last sent control message */ enum pd_ctrl_msg_type fake_prl_get_last_sent_ctrl_msg(int port); + +/** + * Fake to set the last sent control message to an invalid value. + */ +void fake_prl_clear_last_sent_ctrl_msg(int port); #endif #endif /* __CROS_EC_USB_PRL_H */ diff --git a/test/build.mk b/test/build.mk index 9ce5ef8b94..9f2e1eec33 100644 --- a/test/build.mk +++ b/test/build.mk @@ -89,7 +89,9 @@ test-list-host += usb_typec_drp_acc_trysrc test-list-host += usb_prl_old test-list-host += usb_tcpmv2_tcpci test-list-host += usb_prl +test-list-host += usb_prl_noextended test-list-host += usb_pe_drp +test-list-host += usb_pe_drp_noextended test-list-host += utils test-list-host += utils_str test-list-host += vboot @@ -197,8 +199,10 @@ usb_typec_drp_acc_trysrc-y=usb_typec_drp_acc_trysrc.o vpd_api.o \ usb_sm_checks.o usb_prl_old-y=usb_prl_old.o usb_sm_checks.o fake_usbc.o usb_prl-y=usb_prl.o usb_sm_checks.o -usb_pe_drp-y=usb_pe_drp.o usb_sm_checks.o \ - fake_battery.o fake_prl.o fake_usbc.o +usb_prl_noextended-y=usb_prl_noextended.o usb_sm_checks.o fake_usbc.o +usb_pe_drp-y=usb_pe_drp.o usb_sm_checks.o fake_battery.o fake_prl.o fake_usbc.o +usb_pe_drp_noextended-y=usb_pe_drp.o usb_sm_checks.o fake_battery.o fake_prl.o \ + fake_usbc.o usb_tcpmv2_tcpci-y=usb_tcpmv2_tcpci.o vpd_api.o usb_sm_checks.o utils-y=utils.o utils_str-y=utils_str.o diff --git a/test/fake_prl.c b/test/fake_prl.c index f174274318..162e63298f 100644 --- a/test/fake_prl.c +++ b/test/fake_prl.c @@ -60,3 +60,8 @@ enum pd_ctrl_msg_type fake_prl_get_last_sent_ctrl_msg(int port) { return last_ctrl_msg[port]; } + +void fake_prl_clear_last_sent_ctrl_msg(int port) +{ + last_ctrl_msg[port] = 0; +} diff --git a/test/test_config.h b/test/test_config.h index 85c7d29f81..00cf881e4c 100644 --- a/test/test_config.h +++ b/test/test_config.h @@ -314,9 +314,14 @@ int ncp15wb_calculate_temp(uint16_t adc); #define CONFIG_TEST_SM #endif -#if defined(TEST_USB_PRL_OLD) +#if defined(TEST_USB_PRL_OLD) || defined(TEST_USB_PRL_NOEXTENDED) #define CONFIG_USB_PD_PORT_MAX_COUNT 1 #define CONFIG_USB_PD_REV30 + +#if defined(TEST_USB_PRL_OLD) +#define CONFIG_USB_PD_EXTENDED_MESSAGES +#endif + #define CONFIG_USB_PD_TCPMV2 #undef CONFIG_USB_PE_SM #undef CONFIG_USB_TYPEC_SM @@ -332,6 +337,7 @@ int ncp15wb_calculate_temp(uint16_t adc); #if defined(TEST_USB_PRL) #define CONFIG_USB_PD_PORT_MAX_COUNT 1 #define CONFIG_USB_PD_REV30 +#define CONFIG_USB_PD_EXTENDED_MESSAGES #define CONFIG_USB_PD_TCPMV2 #undef CONFIG_USB_PE_SM #undef CONFIG_USB_TYPEC_SM @@ -340,7 +346,7 @@ int ncp15wb_calculate_temp(uint16_t adc); #define CONFIG_USB_POWER_DELIVERY #endif -#if defined(TEST_USB_PE_DRP) +#if defined(TEST_USB_PE_DRP) || defined(TEST_USB_PE_DRP_NOEXTENDED) #define CONFIG_TEST_USB_PE_SM #define CONFIG_USB_PD_PORT_MAX_COUNT 1 #define CONFIG_USB_PE_SM @@ -348,6 +354,11 @@ int ncp15wb_calculate_temp(uint16_t adc); #define CONFIG_USB_POWER_DELIVERY #undef CONFIG_USB_PRL_SM #define CONFIG_USB_PD_REV30 + +#if defined(TEST_USB_PE_DRP) +#define CONFIG_USB_PD_EXTENDED_MESSAGES +#endif + #define CONFIG_USB_PD_TCPMV2 #define CONFIG_USB_PD_DECODE_SOP #undef CONFIG_USB_TYPEC_SM @@ -375,6 +386,7 @@ int ncp15wb_calculate_temp(uint16_t adc); #define CONFIG_USB_PD_PORT_MAX_COUNT 1 #define CONFIG_USB_PD_REV30 +#define CONFIG_USB_PD_EXTENDED_MESSAGES #define CONFIG_USB_PD_TCPMV2 #define CONFIG_USB_PE_SM #define CONFIG_USB_PRL_SM @@ -455,6 +467,7 @@ int ncp15wb_calculate_temp(uint16_t adc); #define CONFIG_SW_CRC #ifdef TEST_USB_PD_REV30 #define CONFIG_USB_PD_REV30 +#define CONFIG_USB_PD_EXTENDED_MESSAGES #define CONFIG_USB_PID 0x5000 #endif #ifdef TEST_USB_PD_GIVEBACK diff --git a/test/usb_pe.h b/test/usb_pe.h index c927437103..f67146bd4d 100644 --- a/test/usb_pe.h +++ b/test/usb_pe.h @@ -131,15 +131,21 @@ enum usb_pe_state { PE_BIST_RX, PE_DR_SNK_GET_SINK_CAP, +#ifdef CONFIG_USB_PD_REV30 /* PD3.0 only states below here*/ PE_FRS_SNK_SRC_START_AMS, +#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES PE_GIVE_BATTERY_CAP, PE_GIVE_BATTERY_STATUS, + PE_SEND_ALERT, +#else + PE_SRC_CHUNK_RECEIVED, + PE_SNK_CHUNK_RECEIVED, +#endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */ -#ifdef CONFIG_USB_PD_REV30 /* Super States */ PE_PRS_FRS_SHARED, -#endif +#endif /* CONFIG_USB_PD_REV30 */ }; void set_state_pe(const int port, const enum usb_pe_state new_state); diff --git a/test/usb_pe_drp.c b/test/usb_pe_drp.c index 2d6a849504..5ea23a11a7 100644 --- a/test/usb_pe_drp.c +++ b/test/usb_pe_drp.c @@ -43,9 +43,16 @@ void pd_set_vbus_discharge(int port, int enable) gpio_set_level(GPIO_USB_C0_DISCHARGE, enable); } +test_static uint8_t tc_enabled = 1; + uint8_t tc_get_pd_enabled(int port) { - return 1; + return tc_enabled; +} + +void pd_comm_enable(int port, int enable) +{ + tc_enabled = !!enable; } bool pd_alt_mode_capable(int port) @@ -57,6 +64,31 @@ void pd_set_suspend(int port, int suspend) { } + +test_static void setup_source(void) +{ + /* Start PE. */ + task_wait_event(10 * MSEC); + pe_set_flag(PORT0, PE_FLAGS_VDM_SETUP_DONE); + pe_set_flag(PORT0, PE_FLAGS_EXPLICIT_CONTRACT); + set_state_pe(PORT0, PE_SRC_READY); + task_wait_event(10 * MSEC); + /* At this point, the PE should be running in PE_SRC_Ready. */ +} + +test_static void setup_sink(void) +{ + tc_set_power_role(PORT0, PD_ROLE_SINK); + pd_comm_enable(PORT0, 0); + task_wait_event(10 * MSEC); + pd_comm_enable(PORT0, 1); + task_wait_event(10 * MSEC); + pe_set_flag(PORT0, PE_FLAGS_VDM_SETUP_DONE); + pe_set_flag(PORT0, PE_FLAGS_EXPLICIT_CONTRACT); + set_state_pe(PORT0, PE_SNK_READY); + task_wait_event(10 * MSEC); + /* At this point, the PE should be running in PE_SNK_Ready. */ +} /** * Test section */ @@ -157,12 +189,105 @@ static int test_vbus_gpio_discharge(void) return EC_SUCCESS; } +test_static int test_extended_message_not_supported(void) +{ + memset(rx_emsg[PORT0].buf, 0, ARRAY_SIZE(rx_emsg[PORT0].buf)); + + /* + * Receive an extended, non-chunked message; expect a Not Supported + * response. + */ + rx_emsg[PORT0].header = PD_HEADER( + PD_DATA_BATTERY_STATUS, PD_ROLE_SINK, PD_ROLE_UFP, 0, + PDO_MAX_OBJECTS, PD_REV30, 1); + *(uint16_t *)rx_emsg[PORT0].buf = + PD_EXT_HEADER(0, 0, ARRAY_SIZE(rx_emsg[PORT0].buf)) & ~BIT(15); + pe_set_flag(PORT0, PE_FLAGS_MSG_RECEIVED); + fake_prl_clear_last_sent_ctrl_msg(PORT0); + task_wait_event(10 * MSEC); + + pe_set_flag(PORT0, PE_FLAGS_TX_COMPLETE); + task_wait_event(10 * MSEC); + TEST_EQ(fake_prl_get_last_sent_ctrl_msg(PORT0), PD_CTRL_NOT_SUPPORTED, + "%d"); + /* At this point, the PE should again be running in PE_SRC_Ready. */ + + /* + * Receive an extended, chunked, single-chunk message; expect a Not + * Supported response. + */ + rx_emsg[PORT0].header = PD_HEADER( + PD_DATA_BATTERY_STATUS, PD_ROLE_SINK, PD_ROLE_UFP, 0, + PDO_MAX_OBJECTS, PD_REV30, 1); + *(uint16_t *)rx_emsg[PORT0].buf = + PD_EXT_HEADER(0, 0, PD_MAX_EXTENDED_MESSAGE_CHUNK_LEN); + pe_set_flag(PORT0, PE_FLAGS_MSG_RECEIVED); + fake_prl_clear_last_sent_ctrl_msg(PORT0); + task_wait_event(10 * MSEC); + + pe_set_flag(PORT0, PE_FLAGS_TX_COMPLETE); + task_wait_event(10 * MSEC); + TEST_EQ(fake_prl_get_last_sent_ctrl_msg(PORT0), PD_CTRL_NOT_SUPPORTED, + "%d"); + /* At this point, the PE should again be running in PE_SRC_Ready. */ + + /* + * Receive an extended, chunked, multi-chunk message; expect a Not + * Supported response after tChunkingNotSupported (not earlier). + */ + rx_emsg[PORT0].header = PD_HEADER( + PD_DATA_BATTERY_STATUS, PD_ROLE_SINK, PD_ROLE_UFP, 0, + PDO_MAX_OBJECTS, PD_REV30, 1); + *(uint16_t *)rx_emsg[PORT0].buf = + PD_EXT_HEADER(0, 0, ARRAY_SIZE(rx_emsg[PORT0].buf)); + pe_set_flag(PORT0, PE_FLAGS_MSG_RECEIVED); + fake_prl_clear_last_sent_ctrl_msg(PORT0); + task_wait_event(10 * MSEC); + /* + * The PE should stay in PE_SRC_Chunk_Received for + * tChunkingNotSupported. + */ + task_wait_event(10 * MSEC); + TEST_NE(fake_prl_get_last_sent_ctrl_msg(PORT0), PD_CTRL_NOT_SUPPORTED, + "%d"); + + task_wait_event(PD_T_CHUNKING_NOT_SUPPORTED); + pe_set_flag(PORT0, PE_FLAGS_TX_COMPLETE); + task_wait_event(10 * MSEC); + TEST_EQ(fake_prl_get_last_sent_ctrl_msg(PORT0), PD_CTRL_NOT_SUPPORTED, + "%d"); + /* At this point, the PE should again be running in PE_SRC_Ready. */ + + /* + * TODO(b/160374787): Test responding with Not Supported to control + * messages requesting extended messages as responses. + */ + + return EC_SUCCESS; +} + +test_static int test_extended_message_not_supported_src(void) +{ + setup_source(); + return test_extended_message_not_supported(); +} + +test_static int test_extended_message_not_supported_snk(void) +{ + setup_sink(); + return test_extended_message_not_supported(); +} + void run_test(int argc, char **argv) { test_reset(); RUN_TEST(test_pe_frs); RUN_TEST(test_vbus_gpio_discharge); +#ifndef CONFIG_USB_PD_EXTENDED_MESSAGES + RUN_TEST(test_extended_message_not_supported_src); + RUN_TEST(test_extended_message_not_supported_snk); +#endif /* Do basic state machine validity checks last. */ RUN_TEST(test_pe_no_parent_cycles); diff --git a/test/usb_pe_drp_noextended.c b/test/usb_pe_drp_noextended.c new file mode 120000 index 0000000000..8351ef8a31 --- /dev/null +++ b/test/usb_pe_drp_noextended.c @@ -0,0 +1 @@ +usb_pe_drp.c
\ No newline at end of file diff --git a/test/usb_pe_drp_noextended.tasklist b/test/usb_pe_drp_noextended.tasklist new file mode 120000 index 0000000000..6d5bcd140f --- /dev/null +++ b/test/usb_pe_drp_noextended.tasklist @@ -0,0 +1 @@ +usb_pe_drp.tasklist
\ No newline at end of file diff --git a/test/usb_prl_noextended.c b/test/usb_prl_noextended.c new file mode 120000 index 0000000000..a47c01a13e --- /dev/null +++ b/test/usb_prl_noextended.c @@ -0,0 +1 @@ +usb_prl_old.c
\ No newline at end of file diff --git a/test/usb_prl_noextended.tasklist b/test/usb_prl_noextended.tasklist new file mode 120000 index 0000000000..26ff35c76c --- /dev/null +++ b/test/usb_prl_noextended.tasklist @@ -0,0 +1 @@ +usb_prl_old.tasklist
\ No newline at end of file diff --git a/test/usb_prl_old.c b/test/usb_prl_old.c index 8a2dea0fd0..e75b81fde2 100644 --- a/test/usb_prl_old.c +++ b/test/usb_prl_old.c @@ -71,6 +71,13 @@ enum usb_prl_hr_state prl_hr_get_state(const int port); enum usb_rch_state rch_get_state(const int port); enum usb_tch_state tch_get_state(const int port); +#ifndef CONFIG_USB_PD_EXTENDED_MESSAGES +enum usb_rch_state rch_get_state(const int port) +{ + return RCH_WAIT_FOR_MESSAGE_FROM_PROTOCOL_LAYER; +} +#endif + static uint32_t test_data[] = { 0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f, @@ -379,7 +386,8 @@ static int simulate_receive_extended_data(int port, return 0; } - if (pd_port[port].mock_pe_message_received) { + if (IS_ENABLED(CONFIG_USB_PD_EXTENDED_MESSAGES) && + pd_port[port].mock_pe_message_received) { ccprintf("Mock pe msg received iteration (%d)\n", j); return 0; } @@ -402,6 +410,12 @@ static int simulate_receive_extended_data(int port, cycle_through_state_machine(port, 1, MSEC); inc_rx_id(port); + if (!IS_ENABLED(CONFIG_USB_PD_EXTENDED_MESSAGES)) { + if (pd_port[port].mock_pe_message_received) + return 1; + return 0; + } + /* * If no more data, do expected to get a chunk request */ @@ -1049,6 +1063,11 @@ static int test_send_extended_data_msg(void) int i; int port = PORT0; + if (!IS_ENABLED(CONFIG_USB_PD_EXTENDED_MESSAGES)) { + ccprints("CONFIG_USB_PD_EXTENDED_MESSAGES disabled; skipping"); + return EC_SUCCESS; + } + enable_prl(port, 1); /* @@ -1199,19 +1218,36 @@ static int test_receive_extended_data_msg(void) enable_prl(port, 1); - /* - * TEST: Receiving extended data message with 29 to 260 bytes - */ + if (IS_ENABLED(CONFIG_USB_PD_EXTENDED_MESSAGES)) { + /* + * TEST: Receiving extended data message with 29 to 260 bytes + */ - task_wake(PD_PORT_TO_TASK_ID(port)); - task_wait_event(40 * MSEC); + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(40 * MSEC); - TEST_EQ(rch_get_state(port), - RCH_WAIT_FOR_MESSAGE_FROM_PROTOCOL_LAYER, "%u"); + TEST_EQ(rch_get_state(port), + RCH_WAIT_FOR_MESSAGE_FROM_PROTOCOL_LAYER, "%u"); - for (len = 29; len <= 260; len++) + for (len = 29; len <= 260; len++) { + TEST_NE(simulate_receive_extended_data(port, + PD_DATA_BATTERY_STATUS, len), 0, "%d"); + } + } else { + /* + * TEST: Receiving unsupported extended data message and then + * subsequently receiving a support non-extended data message. + */ + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(40 * MSEC); TEST_NE(simulate_receive_extended_data(port, - PD_DATA_BATTERY_STATUS, len), 0, "%d"); + PD_DATA_BATTERY_STATUS, 29), 0, "%d"); + + task_wake(PD_PORT_TO_TASK_ID(port)); + task_wait_event(40 * MSEC); + TEST_NE(simulate_receive_data(port, + PD_DATA_BATTERY_STATUS, 28), 0, "%d"); + } enable_prl(port, 0); @@ -1392,6 +1428,8 @@ void run_test(int argc, char **argv) /* TODO(shurst): More PD 2.0 Tests */ + ccprints("Starting PD 3.0 tests"); + /* Test PD 3.0 Protocol */ init_port(PORT0, PD_REV30); RUN_TEST(test_prl_reset); @@ -1418,4 +1456,3 @@ void run_test(int argc, char **argv) test_print_result(); } - |