TCPMv2: Optionally build extended message support

If CONFIG_USB_PD_EXTENDED_MESSAGES is defined, support sending and
receiving extended messages. If it is not, remove the chunking state
machines from the PRL and modify the PE to respond with Not Supported as
appropriate.

BUG=b:160374787,b:158572770
TEST=Attach various devices; observe PD traffic
TEST=make run-usb_prl_noextended; make run-usb_pe_drp_noextended
BRANCH=none

Signed-off-by: Abe Levkoy <alevkoy@chromium.org>
Change-Id: I862020155927b5613d599274708e60678c49c43c
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2304263
Commit-Queue: Jett Rink <jettrink@chromium.org>
Reviewed-by: Jett Rink <jettrink@chromium.org>
This commit is contained in:
Abe Levkoy 2020-07-15 11:03:25 -06:00 committed by Commit Bot
parent a3a577297d
commit 545e72a854
15 changed files with 480 additions and 173 deletions

View File

@ -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

View File

@ -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,11 +543,11 @@ void prl_send_ctrl_msg(int port,
pdmsg[port].xmit_type = type;
pdmsg[port].msg_type = msg;
pdmsg[port].data_objs = 0;
#ifdef CONFIG_USB_PD_REV30
pdmsg[port].ext = 0;
tx_emsg[port].len = 0;
#ifdef CONFIG_USB_PD_EXTENDED_MESSAGES
pdmsg[port].ext = 0;
TCH_SET_FLAG(port, PRL_FLAGS_MSG_XMIT);
#else
PRL_TX_SET_FLAG(port, PRL_FLAGS_MSG_XMIT);
@ -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

View File

@ -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
/******************************************************************************/
/*

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -0,0 +1 @@
usb_pe_drp.c

View File

@ -0,0 +1 @@
usb_pe_drp.tasklist

1
test/usb_prl_noextended.c Symbolic link
View File

@ -0,0 +1 @@
usb_prl_old.c

View File

@ -0,0 +1 @@
usb_prl_old.tasklist

View File

@ -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();
}