From b1fac94e685016318c012d1c5be3fcbd27f2d605 Mon Sep 17 00:00:00 2001 From: Jack Pham Date: Fri, 5 Jun 2020 17:52:21 -0700 Subject: [PATCH 1/3] usb: pd: Correctly handle SVDM versions When receiving an SVDM with an unsupported version, we should still send a response with the highest version we support, rather than dropping the packet outright. Also update the outgoing SVDM version field to 1 (2.0) if operating in PD3 mode. Change-Id: I0bafb619e0ac16bc45064ef699870b0c03b52b47 Signed-off-by: Jack Pham --- drivers/usb/pd/policy_engine.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c index b3d799dfab5b..0916e6cd4927 100644 --- a/drivers/usb/pd/policy_engine.c +++ b/drivers/usb/pd/policy_engine.c @@ -1412,10 +1412,12 @@ int usbpd_send_svdm(struct usbpd *pd, u16 svid, u8 cmd, enum usbpd_svdm_cmd_type cmd_type, int obj_pos, const u32 *vdos, int num_vdos) { - u32 svdm_hdr = SVDM_HDR(svid, 0, obj_pos, cmd_type, cmd); + u32 svdm_hdr = SVDM_HDR(svid, pd->spec_rev == USBPD_REV_30 ? 1 : 0, + obj_pos, cmd_type, cmd); - usbpd_dbg(&pd->dev, "VDM tx: svid:%x cmd:%x cmd_type:%x svdm_hdr:%x\n", - svid, cmd, cmd_type, svdm_hdr); + usbpd_dbg(&pd->dev, "VDM tx: svid:%04x ver:%d obj_pos:%d cmd:%x cmd_type:%x svdm_hdr:%x\n", + svid, pd->spec_rev == USBPD_REV_30 ? 1 : 0, obj_pos, + cmd, cmd_type, svdm_hdr); return usbpd_send_vdm(pd, svdm_hdr, vdos, num_vdos); } @@ -1582,7 +1584,7 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg) ktime_t recvd_time = ktime_get(); usbpd_dbg(&pd->dev, - "VDM rx: svid:%x cmd:%x cmd_type:%x vdm_hdr:%x has_dp: %s\n", + "VDM rx: svid:%04x cmd:%x cmd_type:%x vdm_hdr:%x has_dp: %s\n", svid, cmd, cmd_type, vdm_hdr, pd->has_dp ? "true" : "false"); @@ -1605,11 +1607,9 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg) return; } - if (SVDM_HDR_VER(vdm_hdr) > 1) { - usbpd_dbg(&pd->dev, "Discarding SVDM with incorrect version:%d\n", + if (SVDM_HDR_VER(vdm_hdr) > 1) + usbpd_dbg(&pd->dev, "Received SVDM with unsupported version:%d\n", SVDM_HDR_VER(vdm_hdr)); - return; - } if (cmd_type != SVDM_CMD_TYPE_INITIATOR && pd->current_state != PE_SRC_STARTUP_WAIT_FOR_VDM_RESP) From a74d29a4171675da39a56a5ddc3f2eee47dd91d2 Mon Sep 17 00:00:00 2001 From: Jack Pham Date: Fri, 5 Jun 2020 17:18:27 -0700 Subject: [PATCH 2/3] usb: pd: Allow Status Data Block payloads up to 6 bytes The PD 3.0 V1.2 spec updated the length of the Status Data Block to 6 bytes from 5 bytes. Current handling is checking for the payload length to be exactly 5 bytes and discards it otherwise. Change this to allow reading up to 6 bytes. This also allows the possibility to retrieve a 2-byte Status DB over SOP'/SOP'' from a cable e-marker if needed in the future. Change-Id: I3a78e61b4821c1fd57887276f27be03f73ce5f0f Signed-off-by: Jack Pham --- drivers/usb/pd/policy_engine.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c index 0916e6cd4927..5f43d3efff78 100644 --- a/drivers/usb/pd/policy_engine.c +++ b/drivers/usb/pd/policy_engine.c @@ -275,7 +275,7 @@ static void *usbpd_ipc_log; #define PD_MAX_DATA_OBJ 7 #define PD_SRC_CAP_EXT_DB_LEN 24 -#define PD_STATUS_DB_LEN 5 +#define PD_STATUS_DB_LEN 6 #define PD_BATTERY_CAP_DB_LEN 9 #define PD_MAX_EXT_MSG_LEN 260 @@ -3012,13 +3012,15 @@ static bool handle_ext_snk_ready(struct usbpd *pd, struct rx_msg *rx_msg) complete(&pd->is_ready); break; case MSG_STATUS: - if (rx_msg->data_len != PD_STATUS_DB_LEN) { - usbpd_err(&pd->dev, "Invalid status db\n"); - break; - } + if (rx_msg->data_len > PD_STATUS_DB_LEN) + usbpd_err(&pd->dev, "Invalid status db length:%d\n", + rx_msg->data_len); + + memset(&pd->status_db, 0, sizeof(pd->status_db)); memcpy(&pd->status_db, rx_msg->payload, - sizeof(pd->status_db)); + min((size_t)rx_msg->data_len, sizeof(pd->status_db))); kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE); + complete(&pd->is_ready); break; case MSG_BATTERY_CAPABILITIES: if (rx_msg->data_len != PD_BATTERY_CAP_DB_LEN) { @@ -4009,9 +4011,9 @@ static int usbpd_uevent(struct device *dev, struct kobj_uevent_env *env) "explicit" : "implicit"); add_uevent_var(env, "ALT_MODE=%d", pd->vdm_state == MODE_ENTERED); - add_uevent_var(env, "SDB=%02x %02x %02x %02x %02x", pd->status_db[0], - pd->status_db[1], pd->status_db[2], pd->status_db[3], - pd->status_db[4]); + add_uevent_var(env, "SDB=%02x %02x %02x %02x %02x %02x", + pd->status_db[0], pd->status_db[1], pd->status_db[2], + pd->status_db[3], pd->status_db[4], pd->status_db[5]); return 0; } From 07025f5ba55f12f86b07f33ef5ea6089bddebc6e Mon Sep 17 00:00:00 2001 From: Jack Pham Date: Wed, 27 Oct 2021 22:48:36 -0700 Subject: [PATCH 3/3] usb: pd: Do not respond to SVDM messages in PD 2.0 Since our device does not support responding to Structured VDMs (VIF Responds_to_Discov_SOP_DFP and Responds_to_Discov_SOP_UFP fields are both false), any initiated discovery messages must simply be ignored rather than responding with a NAK. This addresses test failures observed in TEST.PD.VDM.SRC.1, TEST.PD.VDM.SRC.2, TEST.PD.VDM.SNK.1, TEST.PD.VDM.SNK.2, and TEST.PD.VDM.SNK.5 of the USB PD Merged tests. Change-Id: I70f97563e528e4cf6d2a3bce31af7a7c702d4824 Signed-off-by: Jack Pham --- drivers/usb/pd/policy_engine.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c index 5f43d3efff78..f1b1ed9c2362 100644 --- a/drivers/usb/pd/policy_engine.c +++ b/drivers/usb/pd/policy_engine.c @@ -1634,11 +1634,6 @@ static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg) 0, SOP_MSG); if (ret) usbpd_set_state(pd, PE_SEND_SOFT_RESET); - } else { - usbpd_send_svdm(pd, svid, cmd, - SVDM_CMD_TYPE_RESP_NAK, - SVDM_HDR_OBJ_POS(vdm_hdr), - NULL, 0); } } break;