summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--driver/tcpm/tcpci.c16
-rw-r--r--zephyr/test/drivers/usb_malfunction_sink/src/usb_malfunction_sink.c61
2 files changed, 70 insertions, 7 deletions
diff --git a/driver/tcpm/tcpci.c b/driver/tcpm/tcpci.c
index 7924f653b7..84fdbe8cbc 100644
--- a/driver/tcpm/tcpci.c
+++ b/driver/tcpm/tcpci.c
@@ -1221,10 +1221,18 @@ void tcpci_tcpc_alert(int port)
* completion events. This will send an event to the PD tasks
* immediately
*/
- if (alert & TCPC_REG_ALERT_TX_COMPLETE)
- pd_transmit_complete(port, alert & TCPC_REG_ALERT_TX_SUCCESS ?
- TCPC_TX_COMPLETE_SUCCESS :
- TCPC_TX_COMPLETE_FAILED);
+ if (alert & TCPC_REG_ALERT_TX_COMPLETE) {
+ int tx_status;
+
+ if (alert & TCPC_REG_ALERT_TX_SUCCESS)
+ tx_status = TCPC_TX_COMPLETE_SUCCESS;
+ else if (alert & TCPC_REG_ALERT_TX_DISCARDED)
+ tx_status = TCPC_TX_COMPLETE_DISCARDED;
+ else
+ tx_status = TCPC_TX_COMPLETE_FAILED;
+
+ pd_transmit_complete(port, tx_status);
+ }
tcpc_get_bist_test_mode(port, &bist_mode);
diff --git a/zephyr/test/drivers/usb_malfunction_sink/src/usb_malfunction_sink.c b/zephyr/test/drivers/usb_malfunction_sink/src/usb_malfunction_sink.c
index fd6cab7bad..dd50f2b35b 100644
--- a/zephyr/test/drivers/usb_malfunction_sink/src/usb_malfunction_sink.c
+++ b/zephyr/test/drivers/usb_malfunction_sink/src/usb_malfunction_sink.c
@@ -248,14 +248,14 @@ ZTEST_F(usb_malfunction_sink, test_ignore_source_cap_and_pd_disable)
struct ec_response_typec_status typec_status;
/*
- * Ignore first SourceCapabilities message and discard others by sending
- * different messages. This will lead to PD disable.
+ * Ignore first SourceCapabilities message and failed others.
+ * This will lead to PD disable.
*/
fixture->actions[0].action_mask = TCPCI_FAULTY_EXT_IGNORE_SRC_CAP;
fixture->actions[0].count = 1;
tcpci_faulty_ext_append_action(&fixture->faulty_snk_ext,
&fixture->actions[0]);
- fixture->actions[1].action_mask = TCPCI_FAULTY_EXT_DISCARD_SRC_CAP;
+ fixture->actions[1].action_mask = TCPCI_FAULTY_EXT_FAIL_SRC_CAP;
fixture->actions[1].count = TCPCI_FAULTY_EXT_INFINITE_ACTION;
tcpci_faulty_ext_append_action(&fixture->faulty_snk_ext,
&fixture->actions[1]);
@@ -270,3 +270,58 @@ ZTEST_F(usb_malfunction_sink, test_ignore_source_cap_and_pd_disable)
zassert_true(typec_status.dev_connected);
zassert_false(typec_status.sop_connected);
}
+
+ZTEST_F(usb_malfunction_sink, test_discard_source_cap)
+{
+ struct tcpci_partner_log_msg *msg;
+ uint16_t header;
+ int msg_cnt = 0;
+
+ /*
+ * Discard SourceCapabilities messages, this will lead to SoftReset.
+ */
+ fixture->actions[0].action_mask = TCPCI_FAULTY_EXT_DISCARD_SRC_CAP;
+ fixture->actions[0].count = TCPCI_FAULTY_EXT_INFINITE_ACTION;
+ tcpci_faulty_ext_append_action(&fixture->faulty_snk_ext,
+ &fixture->actions[0]);
+
+ tcpci_partner_common_enable_pd_logging(&fixture->sink, true);
+ connect_sink_to_port(&fixture->sink, fixture->tcpci_emul,
+ fixture->charger_emul);
+ tcpci_partner_common_enable_pd_logging(&fixture->sink, false);
+
+ /*
+ * Check if SourceCapability message alternate with Accept and
+ * SoftReset.
+ * The sequence will be
+ * TCPM: SourceCapability -> TCPC: Accept -> TCPM: SoftReset ->
+ * TCPC: Accept
+ */
+ SYS_SLIST_FOR_EACH_CONTAINER(&fixture->sink.msg_log, msg, node)
+ {
+ header = sys_get_le16(msg->buf);
+
+ switch (msg_cnt % 4) {
+ case 0:
+ zassert_equal(
+ PD_HEADER_TYPE(header), PD_DATA_SOURCE_CAP,
+ "Expected message %d to be SourceCapabilities, not 0x%x",
+ msg_cnt, PD_HEADER_TYPE(header));
+ break;
+ case 1:
+ case 3:
+ zassert_equal(
+ PD_HEADER_TYPE(header), PD_CTRL_ACCEPT,
+ "Expected message %d to be Accept, not 0x%x",
+ msg_cnt, PD_HEADER_TYPE(header));
+ break;
+ case 2:
+ zassert_equal(
+ PD_HEADER_TYPE(header), PD_CTRL_SOFT_RESET,
+ "Expected message %d to be SoftReset, not 0x%x",
+ msg_cnt, PD_HEADER_TYPE(header));
+ break;
+ }
+ msg_cnt++;
+ }
+}