Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb: typec: tcpm: Correct the responses in SVDM Version 2.0 DFP

In USB PD Spec Rev 3.1 Ver 1.0, section "6.12.5 Applicability of
Structured VDM Commands", DFP is allowed and recommended to respond to
Discovery Identity with ACK. And in section "6.4.4.2.5.1 Commands other
than Attention", NAK should be returned only when receiving Messages
with invalid fields, Messages in wrong situation, or unrecognize
Messages.

Still keep the original design for SVDM Version 1.0 for backward
compatibilities.

Fixes: 193a68011fdc ("staging: typec: tcpm: Respond to Discover Identity commands")
Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Kyle Tso <kyletso@google.com>
Link: https://lore.kernel.org/r/20210601123151.3441914-2-kyletso@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Kyle Tso and committed by
Greg Kroah-Hartman
f41bfc7e 8f11fe7e

+10 -4
+10 -4
drivers/usb/typec/tcpm/tcpm.c
··· 1547 1547 if (PD_VDO_VID(p[0]) != USB_SID_PD) 1548 1548 break; 1549 1549 1550 - if (PD_VDO_SVDM_VER(p[0]) < svdm_version) 1550 + if (PD_VDO_SVDM_VER(p[0]) < svdm_version) { 1551 1551 typec_partner_set_svdm_version(port->partner, 1552 1552 PD_VDO_SVDM_VER(p[0])); 1553 + svdm_version = PD_VDO_SVDM_VER(p[0]); 1554 + } 1553 1555 1554 1556 tcpm_ams_start(port, DISCOVER_IDENTITY); 1555 - /* 6.4.4.3.1: Only respond as UFP (device) */ 1556 - if (port->data_role == TYPEC_DEVICE && 1557 + /* 1558 + * PD2.0 Spec 6.10.3: respond with NAK as DFP (data host) 1559 + * PD3.1 Spec 6.4.4.2.5.1: respond with NAK if "invalid field" or 1560 + * "wrong configuation" or "Unrecognized" 1561 + */ 1562 + if ((port->data_role == TYPEC_DEVICE || svdm_version >= SVDM_VER_2_0) && 1557 1563 port->nr_snk_vdo) { 1558 1564 /* 1559 1565 * Product Type DFP and Connector Type are not defined in SVDM 1560 1566 * version 1.0 and shall be set to zero. 1561 1567 */ 1562 - if (typec_get_negotiated_svdm_version(typec) < SVDM_VER_2_0) 1568 + if (svdm_version < SVDM_VER_2_0) 1563 1569 response[1] = port->snk_vdo[0] & ~IDH_DFP_MASK 1564 1570 & ~IDH_CONN_MASK; 1565 1571 else