diff options
author | Ayushee <ayushee.shah@intel.com> | 2020-01-28 14:53:21 -0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-01-31 01:49:49 +0000 |
commit | d181c052e5c90f78fa2dde64c82690962de39fb5 (patch) | |
tree | 7e0e25e5436467eeefb85bec3fca7cae3c1d32db | |
parent | 71aadcd324ddfcdde2168247d7ef2d19b69db36e (diff) | |
download | chrome-ec-d181c052e5c90f78fa2dde64c82690962de39fb5.tar.gz |
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 <ayushee.shah@intel.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2026650
Reviewed-by: Keith Short <keithshort@chromium.org>
-rw-r--r-- | common/usb_pd_policy.c | 47 | ||||
-rw-r--r-- | common/usb_pd_protocol.c | 8 | ||||
-rw-r--r-- | 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; @@ -1683,6 +1685,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 * * @param port USB-C port number |