summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/usbc/usb_pe_drp_sm.c229
-rw-r--r--common/usbc/usb_prl_sm.c84
-rw-r--r--include/config.h14
-rw-r--r--include/usb_pd.h89
-rw-r--r--include/usb_prl_sm.h5
-rw-r--r--test/build.mk8
-rw-r--r--test/fake_prl.c5
-rw-r--r--test/test_config.h17
-rw-r--r--test/usb_pe.h10
-rw-r--r--test/usb_pe_drp.c127
l---------test/usb_pe_drp_noextended.c1
l---------test/usb_pe_drp_noextended.tasklist1
l---------test/usb_prl_noextended.c1
l---------test/usb_prl_noextended.tasklist1
-rw-r--r--test/usb_prl_old.c59
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();
}
-