From d181c052e5c90f78fa2dde64c82690962de39fb5 Mon Sep 17 00:00:00 2001 From: Ayushee Date: Tue, 28 Jan 2020 14:53:21 -0800 Subject: usb_pd TCPMv1: Maintain independent MessageID for SOP Prime This patchset enables storage of MessageId counter received from the cable plug. Since SOP*(Cable) communication and SOP(Port Partner) have separate MessageID counters, it is necessary to store separate messageIDs to avoid the the incoming packets from getting dropped. BUG=b:148481858 BRANCH=None TEST=Tested on Volteer, able to maintain separate MessageId count for SOP and SOP' communication. Change-Id: Iac2dc616f99a9e19914588e59441df8b09068afa Signed-off-by: Ayushee Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2026650 Reviewed-by: Keith Short --- common/usb_pd_policy.c | 47 ++++++++++++++++++++++++++++++++++++++--------- common/usb_pd_protocol.c | 8 ++++++++ include/usb_pd.h | 22 ++++++++++++++++++++++ 3 files changed, 68 insertions(+), 9 deletions(-) diff --git a/common/usb_pd_policy.c b/common/usb_pd_policy.c index 1b582b75d4..7ff9c3342d 100644 --- a/common/usb_pd_policy.c +++ b/common/usb_pd_policy.c @@ -167,12 +167,30 @@ int pd_charge_from_device(uint16_t vid, uint16_t pid) static struct pd_cable cable[CONFIG_USB_PD_PORT_MAX_COUNT]; -static bool is_transmit_msg_sop_prime(int port) +bool is_transmit_msg_sop_prime(int port) { return (IS_ENABLED(CONFIG_USB_PD_DECODE_SOP) && (cable[port].flags & CABLE_FLAGS_SOP_PRIME_ENABLE)); } +int cable_consume_repeat_message(int port, uint8_t msg_id) +{ + + if (cable[port].last_cable_msg_id != msg_id) { + cable[port].last_cable_msg_id = msg_id; + return 0; + } + CPRINTF("C%d Cable repeat msg_id %d\n", port, msg_id); + return 1; + +} + +static void disable_transmit_sop_prime(int port) +{ + if (IS_ENABLED(CONFIG_USB_PD_DECODE_SOP)) + cable[port].flags &= ~CABLE_FLAGS_SOP_PRIME_ENABLE; +} + uint8_t is_sop_prime_ready(int port, enum pd_data_role data_role, uint32_t pd_flags) @@ -189,16 +207,33 @@ uint8_t is_sop_prime_ready(int port, * ensure that it is the Vconn Source */ if (pd_flags & PD_FLAGS_VCONN_ON && (IS_ENABLED(CONFIG_USB_PD_REV30) || - data_role == PD_ROLE_DFP)) + data_role == PD_ROLE_DFP)) { return is_transmit_msg_sop_prime(port); + } + if (is_transmit_msg_sop_prime(port)) { + /* + * Clear the CABLE_FLAGS_SOP_PRIME_ENABLE flag if the port is + * unable to communicate with the cable plug. + */ + disable_transmit_sop_prime(port); + } return 0; } void reset_pd_cable(int port) { - if (IS_ENABLED(CONFIG_USB_PD_DECODE_SOP)) + if (IS_ENABLED(CONFIG_USB_PD_DECODE_SOP)) { memset(&cable[port], 0, sizeof(cable[port])); + /* + * Invalidate the last cable messageId counter. The cable + * Message id starts from 0 to 7 and if last_cable msg_id + * is initialized to 0, it will lead to repetitive message + * id with first received packet. Hence, initialize it with + * an invalid value 0xff. + */ + cable[port].last_cable_msg_id = 0xff; + } } enum idh_ptype get_usb_pd_cable_type(int port) @@ -333,12 +368,6 @@ static void enable_transmit_sop_prime(int port) cable[port].flags |= CABLE_FLAGS_SOP_PRIME_ENABLE; } -static void disable_transmit_sop_prime(int port) -{ - if (IS_ENABLED(CONFIG_USB_PD_DECODE_SOP)) - cable[port].flags &= ~CABLE_FLAGS_SOP_PRIME_ENABLE; -} - static bool is_tbt_compat_enabled(int port) { return (IS_ENABLED(CONFIG_USB_PD_TBT_COMPAT_MODE) && diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index 6e29bf06b8..18a6afdfbb 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -700,6 +700,14 @@ static int consume_repeat_message(int port, uint16_t msg_header) if (PD_HEADER_TYPE(msg_header) == PD_CTRL_SOFT_RESET && PD_HEADER_CNT(msg_header) == 0) { return 0; + /* TODO: Check for incoming SOP'' messages */ + } else if (is_transmit_msg_sop_prime(port)) { + /* + * From USB PD version 1.3 section 6.7.1, the port which + * communicates using SOP* Packets Shall maintain copy + * of the last MessageID for each type of SOP* it uses. + */ + return cable_consume_repeat_message(port, msg_id); } else if (pd[port].last_msg_id != msg_id) { pd[port].last_msg_id = msg_id; } else if (pd[port].last_msg_id == msg_id) { diff --git a/include/usb_pd.h b/include/usb_pd.h index eaff1212c9..8ce6335b7d 100644 --- a/include/usb_pd.h +++ b/include/usb_pd.h @@ -529,6 +529,8 @@ enum pd_rev_type { /* Cable structure for storing cable attributes */ struct pd_cable { + /* Last received cable message id counter*/ + uint8_t last_cable_msg_id; uint8_t is_identified; /* Type of cable */ enum idh_ptype type; @@ -1682,6 +1684,26 @@ uint32_t *pd_get_mode_vdo(int port, uint16_t svid_idx); */ struct svdm_amode_data *pd_get_amode_data(int port, uint16_t svid); +/** + * Returns 0 if previous cable messageId count is different from received + * messageId count. + * + * @param port USB-C port number + * @param msg_id Received cable msg_id + * @return 0 if Received MessageId count is different from the + * previous one. + * 1 Otherwise + */ +int cable_consume_repeat_message(int port, uint8_t msg_id); + +/** + * Returns status of CABLE_FLAGS_SOP_PRIME_ENABLE flag + * + * @param port USB-C port number + * @return Status of CABLE_FLAGS_SOP_PRIME_ENABLE flag + */ +bool is_transmit_msg_sop_prime(int port); + /** * Returns the status of cable flag - CABLE_FLAGS_SOP_PRIME_ENABLE * -- cgit v1.2.1