summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVijay Hiremath <vijay.p.hiremath@intel.com>2019-12-16 21:29:05 -0800
committerCommit Bot <commit-bot@chromium.org>2019-12-23 15:07:35 +0000
commitd804391337b43e25eb2b4dfada37309dc89b3285 (patch)
tree78cc9afd72d34c1619f73dee3ac33e75b19385de
parentadf28b166427442c3534e6e70b2da9f39d11ced6 (diff)
downloadchrome-ec-d804391337b43e25eb2b4dfada37309dc89b3285.tar.gz
TCPMv1: TBT: Correct checking for Intel SVIDs
To be able to enter into Thunderbolt-compatible mode, responder must present the Intel SVID. Responder may have multiple SVIDs and also responder may present the SVIDs in any order hence check all SVIDs if Intel SVID is present. BUG=b:146081601 BRANCH=none TEST=Able to verify on TGLRVP, both device & cable SVIDs are verified for Intel SVID before entering Thunderbolt-compatible mode. Change-Id: I5a07080c8fd610c041f7225bc004617605a7056c Signed-off-by: Vijay Hiremath <vijay.p.hiremath@intel.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1970922 Reviewed-by: Abe Levkoy <alevkoy@chromium.org> Reviewed-by: Diana Z <dzigterman@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1979584 Tested-by: Tim Wawrzynczak <twawrzynczak@chromium.org> Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org> Commit-Queue: Tim Wawrzynczak <twawrzynczak@chromium.org>
-rw-r--r--common/usb_pd_policy.c137
1 files changed, 136 insertions, 1 deletions
diff --git a/common/usb_pd_policy.c b/common/usb_pd_policy.c
index f31f859641..0348716815 100644
--- a/common/usb_pd_policy.c
+++ b/common/usb_pd_policy.c
@@ -223,7 +223,113 @@ static void enable_transmit_sop_prime(int port)
static void disable_transmit_sop_prime(int port)
{
- cable[port].flags &= ~CABLE_FLAGS_SOP_PRIME_ENABLE;
+ 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) &&
+ (cable[port].flags & CABLE_FLAGS_TBT_COMPAT_ENABLE));
+}
+
+static void enable_tbt_compat_mode(int port)
+{
+ if (IS_ENABLED(CONFIG_USB_PD_TBT_COMPAT_MODE))
+ cable[port].flags |= CABLE_FLAGS_TBT_COMPAT_ENABLE;
+}
+
+static inline void disable_tbt_compat_mode(int port)
+{
+ if (IS_ENABLED(CONFIG_USB_PD_TBT_COMPAT_MODE))
+ cable[port].flags &= ~CABLE_FLAGS_TBT_COMPAT_ENABLE;
+}
+
+/*
+ * TODO (b/146006708): Make the below three functions independent of
+ * Thunderbolt-compatible mode enabled as these USB PD 3.0 VDO responses
+ * can be used to identify other cable attributes like cable speed.
+ */
+static bool is_cable_superspeed(int port)
+{
+ if (is_tbt_compat_enabled(port) &&
+ IS_ENABLED(CONFIG_USB_PD_DECODE_SOP)) {
+ /*
+ * Bit 4 gives if USB SS is supported for active cables
+ * for Rev 3.0
+ * Ref: PD Spec 3.0 Active Cable VDO 2
+ */
+ if (IS_ENABLED(CONFIG_USB_PD_REV30) &&
+ (cable[port].type == IDH_PTYPE_ACABLE))
+ return !!cable[port].attr2.a2_rev30.usb_ss_support;
+
+ /*
+ * Bits 2:0 gives USB SS support for passive cable
+ * for both Rev2.0 and Rev3.0
+ * Ref: PD Spec 3.0 Passive cable VDO and
+ * Spec 2.0 Passive cable VDO
+ *
+ * For rev2.0 active cable, bits 2:0 give USB SS support
+ * (Ref: spec 2.0 Passive cable VDO)
+ */
+ return !!(cable[port].attr.rev20.ss & USB_SS_U31_GEN2);
+ }
+ return false;
+}
+
+/* Check if product supports any Modal Operation (Alternate Modes) */
+static bool is_modal(int port, int cnt, uint32_t *payload)
+{
+ return (is_tbt_compat_enabled(port) &&
+ is_vdo_present(cnt, VDO_INDEX_IDH) &&
+ PD_IDH_IS_MODAL(payload[VDO_INDEX_IDH]));
+}
+
+static bool is_intel_svid(int port, int prev_svid_cnt)
+{
+ int i;
+
+ /*
+ * Check if SVID0 = USB_VID_INTEL
+ * (Ref: USB Type-C cable and connector specification, Table F-9)
+ */
+ if (is_tbt_compat_enabled(port)) {
+ /*
+ * errata: All the Thunderbolt certified cables and docks
+ * tested have SVID1 = 0x8087
+ *
+ * For the Discover SVIDs, responder may present the SVIDs
+ * in any order hence check all SVIDs if Intel SVID present.
+ */
+ for (i = prev_svid_cnt; i < pe[port].svid_cnt; i++) {
+ if (pe[port].svids[i].svid == USB_VID_INTEL)
+ return true;
+ }
+ }
+ return false;
+}
+
+static inline bool is_tbt_compat_mode(int port, int cnt, uint32_t *payload)
+{
+ /*
+ * Ref: USB Type-C cable and connector specification
+ * F.2.5 TBT3 Device Discover Mode Responses
+ */
+
+ return is_tbt_compat_enabled(port) &&
+ is_vdo_present(cnt, VDO_INDEX_IDH) &&
+ PD_VDO_RESP_MODE_INTEL_TBT(payload[VDO_INDEX_IDH]);
+}
+
+static inline void limit_cable_speed(int port)
+{
+ cable[port].flags |= CABLE_FLAGS_TBT_COMPAT_LIMIT_SPEED;
+}
+
+static inline bool is_limit_cable_speed(int port)
+{
+ return !!(cable[port].flags & CABLE_FLAGS_TBT_COMPAT_LIMIT_SPEED);
+>>>>>>> 78c2dcc67c... TCPMv1: TBT: Correct checking for Intel SVIDs
}
void pd_dfp_pe_init(int port)
@@ -742,8 +848,37 @@ int pd_svdm(int port, int cnt, uint32_t *payload, uint32_t **rpayload)
#endif
break;
case CMD_DISCOVER_SVID:
+ {
+ int prev_svid_cnt = pe[port].svid_cnt;
dfp_consume_svids(port, cnt, payload);
+ /*
+ * Check if 0x8087 is received for Discover SVID SOP.
+ * If not, disable Thunderbolt-compatible mode
+ * Ref: USB Type-C Cable and Connector Specification,
+ * figure F-1: TBT3 Discovery Flow
+ */
+ if (is_intel_svid(port, prev_svid_cnt)) {
+ if (!is_transmit_msg_sop_prime(port)) {
+ rsize = dfp_discover_svids(payload);
+ enable_transmit_sop_prime(port);
+ break;
+ }
+ /*
+ * If 0x8087 is not received for Discover SVID SOP'
+ * limit to TBT passive Gen 2 cable
+ * Ref: USB Type-C Cable and Connector Specification,
+ * figure F-1: TBT3 Discovery Flow
+ */
+ } else if (is_tbt_compat_enabled(port) &&
+ is_transmit_msg_sop_prime(port)) {
+ limit_cable_speed(port);
+ } else {
+ disable_tbt_compat_mode(port);
+ }
+
rsize = dfp_discover_modes(port, payload);
+ disable_transmit_sop_prime(port);
+ }
break;
case CMD_DISCOVER_MODES:
dfp_consume_modes(port, cnt, payload);