summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAyushee <ayushee.shah@intel.com>2020-01-28 14:53:21 -0800
committerCommit Bot <commit-bot@chromium.org>2020-01-31 01:49:49 +0000
commitd181c052e5c90f78fa2dde64c82690962de39fb5 (patch)
tree7e0e25e5436467eeefb85bec3fca7cae3c1d32db
parent71aadcd324ddfcdde2168247d7ef2d19b69db36e (diff)
downloadchrome-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.c47
-rw-r--r--common/usb_pd_protocol.c8
-rw-r--r--include/usb_pd.h22
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