summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Michalec <tm@semihalf.com>2022-03-14 14:16:37 +0100
committerCommit Bot <commit-bot@chromium.org>2022-03-18 14:21:06 +0000
commit3f20cb6990a1220b1c1630d46b905fcc77c452f4 (patch)
treed98d625662fbce0fa127c9ff90a358125dcaa545
parentf4f609046666cfa2ceb7452560463f4a6ad2baea (diff)
downloadchrome-ec-3f20cb6990a1220b1c1630d46b905fcc77c452f4.tar.gz
zephyr: emul: Add disconnect callback to TCPCI partner
Add disconnect callback which is used by TCPCI to inform partner emulator. Partner emulator clears delayed messages queue and stops timers on disconnection. PD messages cannot be send when partner emulator is disconnected. BUG=none BRANCH=none TEST=zmake configure --test test-drivers Signed-off-by: Tomasz Michalec <tm@semihalf.com> Change-Id: Idd3023a268affcdd1417b40745a24e297df74f8e Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3528402 Reviewed-by: Aaron Massey <aaronmassey@google.com> Reviewed-by: Abe Levkoy <alevkoy@chromium.org> Commit-Queue: Tomasz Michalec <tmichalec@google.com> Tested-by: Tomasz Michalec <tmichalec@google.com>
-rw-r--r--zephyr/emul/tcpc/emul_tcpci.c109
-rw-r--r--zephyr/emul/tcpc/emul_tcpci_partner_common.c11
-rw-r--r--zephyr/emul/tcpc/emul_tcpci_partner_drp.c17
-rw-r--r--zephyr/emul/tcpc/emul_tcpci_partner_snk.c17
-rw-r--r--zephyr/emul/tcpc/emul_tcpci_partner_src.c17
-rw-r--r--zephyr/include/emul/tcpc/emul_tcpci.h9
-rw-r--r--zephyr/include/emul/tcpc/emul_tcpci_partner_common.h9
-rw-r--r--zephyr/test/drivers/src/integration/usbc/usb.c1
8 files changed, 138 insertions, 52 deletions
diff --git a/zephyr/emul/tcpc/emul_tcpci.c b/zephyr/emul/tcpc/emul_tcpci.c
index c97d002edd..6ee2e12f0f 100644
--- a/zephyr/emul/tcpc/emul_tcpci.c
+++ b/zephyr/emul/tcpc/emul_tcpci.c
@@ -253,6 +253,57 @@ static int tcpci_emul_alert_changed(const struct emul *emul)
return 0;
}
+/**
+ * @brief Load next rx message and inform partner which message was consumed
+ * by TCPC
+ *
+ * @param emul Pointer to TCPCI emulator
+ *
+ * @return 0 when there is no new message to load
+ * @return 1 when new rx message is loaded
+ */
+static int tcpci_emul_get_next_rx_msg(const struct emul *emul)
+{
+ struct tcpci_emul_data *data = emul->data;
+ struct tcpci_emul_msg *consumed_msg;
+
+ if (data->rx_msg == NULL) {
+ return 0;
+ }
+
+ consumed_msg = data->rx_msg;
+ data->rx_msg = consumed_msg->next;
+
+ /* Inform partner */
+ if (data->partner && data->partner->rx_consumed) {
+ data->partner->rx_consumed(emul, data->partner, consumed_msg);
+ }
+
+ /* Prepare new loaded message */
+ if (data->rx_msg) {
+ data->rx_msg->idx = 0;
+
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * @brief Perform actions that are expected by TCPC on disabling PD message
+ * delivery (clear RECEIVE_DETECT register and clear already received
+ * messages in buffer)
+ *
+ * @param emul Pointer to TCPCI emulator
+ */
+static void tcpci_emul_disable_pd_msg_delivery(const struct emul *emul)
+{
+ tcpci_emul_set_reg(emul, TCPC_REG_RX_DETECT, 0);
+ /* Clear received messages */
+ while (tcpci_emul_get_next_rx_msg(emul))
+ ;
+}
+
/** Check description in emul_tcpci.h */
int tcpci_emul_add_rx_msg(const struct emul *emul,
struct tcpci_emul_msg *rx_msg, bool alert)
@@ -474,7 +525,12 @@ int tcpci_emul_disconnect_partner(const struct emul *emul)
uint16_t term;
int rc;
+ tcpci_emul_disable_pd_msg_delivery(emul);
+ if (data->partner && data->partner->disconnect) {
+ data->partner->disconnect(emul, data->partner);
+ }
data->partner = NULL;
+
/* Set both CC lines to open to indicate disconnect. */
rc = tcpci_emul_get_reg(emul, TCPC_REG_CC_STATUS, &val);
if (rc != 0)
@@ -1114,58 +1170,6 @@ static int tcpci_emul_handle_command(const struct emul *emul)
}
/**
- * @brief Load next rx message and inform partner which message was consumed
- * by TCPC
- *
- * @param emul Pointer to TCPCI emulator
- *
- * @return 0 when there is no new message to load
- * @return 1 when new rx message is loaded
- */
-static int tcpci_emul_get_next_rx_msg(const struct emul *emul)
-{
- struct tcpci_emul_data *data = emul->data;
- struct tcpci_emul_msg *consumed_msg;
-
- if (data->rx_msg == NULL) {
- return 0;
- }
-
- consumed_msg = data->rx_msg;
- data->rx_msg = consumed_msg->next;
-
- /* Inform partner */
- if (data->partner && data->partner->rx_consumed) {
- data->partner->rx_consumed(emul, data->partner, consumed_msg);
- }
-
- /* Prepare new loaded message */
- if (data->rx_msg) {
- data->rx_msg->idx = 0;
-
- return 1;
- }
-
- return 0;
-}
-
-/**
- * @brief Perform actions that are expected by TCPC on disabling PD message
- * delivery (clear RECEIVE_DETECT register, clear already received
- * messages in buffer and reset mask registers)
- *
- * @param emul Pointer to TCPCI emulator
- */
-static void tcpci_emul_disable_pd_msg_delivery(const struct emul *emul)
-{
- tcpci_emul_set_reg(emul, TCPC_REG_RX_DETECT, 0);
- /* Clear received messages */
- while (tcpci_emul_get_next_rx_msg(emul))
- ;
- tcpci_emul_reset_mask_regs(emul);
-}
-
-/**
* @brief Handle write to transmit register
*
* @param emul Pointer to TCPCI emulator
@@ -1199,6 +1203,7 @@ static int tcpci_emul_handle_transmit(const struct emul *emul)
switch (type) {
case TCPCI_MSG_TX_HARD_RESET:
tcpci_emul_disable_pd_msg_delivery(emul);
+ tcpci_emul_reset_mask_regs(emul);
/* fallthrough */
case TCPCI_MSG_CABLE_RESET:
/*
diff --git a/zephyr/emul/tcpc/emul_tcpci_partner_common.c b/zephyr/emul/tcpc/emul_tcpci_partner_common.c
index 69b2e3013b..983c9735f2 100644
--- a/zephyr/emul/tcpc/emul_tcpci_partner_common.c
+++ b/zephyr/emul/tcpc/emul_tcpci_partner_common.c
@@ -146,6 +146,8 @@ static void tcpci_partner_delayed_send(void *fifo_data)
k_mutex_unlock(&data->to_send_mutex);
tcpci_partner_set_header(data, msg);
+ __ASSERT(data->tcpci_emul,
+ "Disconnected partner send message");
ret = tcpci_emul_add_rx_msg(data->tcpci_emul, &msg->msg,
true /* send alert */);
tcpci_partner_log_msg(data, &msg->msg,
@@ -218,6 +220,7 @@ int tcpci_partner_send_msg(struct tcpci_partner_data *data,
int ret;
if (delay == 0) {
+ __ASSERT(data->tcpci_emul, "Disconnected partner send message");
tcpci_partner_set_header(data, msg);
ret = tcpci_emul_add_rx_msg(data->tcpci_emul, &msg->msg, true);
tcpci_partner_log_msg(data, &msg->msg,
@@ -554,6 +557,14 @@ void tcpci_partner_common_handler_mask_msg(struct tcpci_partner_data *data,
}
/** Check description in emul_common_tcpci_partner.h */
+void tcpci_partner_common_disconnect(struct tcpci_partner_data *data)
+{
+ tcpci_partner_clear_msg_queue(data);
+ tcpci_partner_stop_sender_response_timer(data);
+ data->tcpci_emul = NULL;
+}
+
+/** Check description in emul_common_tcpci_partner.h */
int tcpci_partner_common_enable_pd_logging(struct tcpci_partner_data *data,
bool enable)
{
diff --git a/zephyr/emul/tcpc/emul_tcpci_partner_drp.c b/zephyr/emul/tcpc/emul_tcpci_partner_drp.c
index 08a6fd7b5e..f69ebc5d85 100644
--- a/zephyr/emul/tcpc/emul_tcpci_partner_drp.c
+++ b/zephyr/emul/tcpc/emul_tcpci_partner_drp.c
@@ -240,6 +240,22 @@ static void tcpci_drp_emul_rx_consumed_op(
tcpci_partner_free_msg(msg);
}
+/**
+ * @brief Function called when emulator is disconnected from TCPCI
+ *
+ * @param emul Pointer to TCPCI emulator
+ * @param ops Pointer to partner operations structure
+ */
+static void tcpci_drp_emul_disconnect_op(
+ const struct emul *emul,
+ const struct tcpci_emul_partner_ops *ops)
+{
+ struct tcpci_drp_emul *drp_emul =
+ CONTAINER_OF(ops, struct tcpci_drp_emul, ops);
+
+ tcpci_partner_common_disconnect(&drp_emul->common_data);
+}
+
/** Check description in emul_tcpci_partner_drp.h */
int tcpci_drp_emul_connect_to_tcpci(struct tcpci_drp_emul_data *data,
struct tcpci_src_emul_data *src_data,
@@ -270,6 +286,7 @@ void tcpci_drp_emul_init(struct tcpci_drp_emul *emul)
emul->ops.transmit = tcpci_drp_emul_transmit_op;
emul->ops.rx_consumed = tcpci_drp_emul_rx_consumed_op;
emul->ops.control_change = NULL;
+ emul->ops.disconnect = tcpci_drp_emul_disconnect_op;
emul->data.sink = true;
emul->data.in_pwr_swap = false;
diff --git a/zephyr/emul/tcpc/emul_tcpci_partner_snk.c b/zephyr/emul/tcpc/emul_tcpci_partner_snk.c
index 82838a6618..052193ac40 100644
--- a/zephyr/emul/tcpc/emul_tcpci_partner_snk.c
+++ b/zephyr/emul/tcpc/emul_tcpci_partner_snk.c
@@ -477,6 +477,22 @@ static void tcpci_snk_emul_rx_consumed_op(
tcpci_partner_free_msg(msg);
}
+/**
+ * @brief Function called when emulator is disconnected from TCPCI
+ *
+ * @param emul Pointer to TCPCI emulator
+ * @param ops Pointer to partner operations structure
+ */
+static void tcpci_snk_emul_disconnect_op(
+ const struct emul *emul,
+ const struct tcpci_emul_partner_ops *ops)
+{
+ struct tcpci_snk_emul *snk_emul =
+ CONTAINER_OF(ops, struct tcpci_snk_emul, ops);
+
+ tcpci_partner_common_disconnect(&snk_emul->common_data);
+}
+
/** Check description in emul_tcpci_snk.h */
int tcpci_snk_emul_connect_to_tcpci(struct tcpci_snk_emul_data *data,
struct tcpci_partner_data *common_data,
@@ -526,6 +542,7 @@ void tcpci_snk_emul_init(struct tcpci_snk_emul *emul)
emul->ops.transmit = tcpci_snk_emul_transmit_op;
emul->ops.rx_consumed = tcpci_snk_emul_rx_consumed_op;
emul->ops.control_change = NULL;
+ emul->ops.disconnect = tcpci_snk_emul_disconnect_op;
tcpci_snk_emul_init_data(&emul->data);
}
diff --git a/zephyr/emul/tcpc/emul_tcpci_partner_src.c b/zephyr/emul/tcpc/emul_tcpci_partner_src.c
index 99b9d5581b..504b05504f 100644
--- a/zephyr/emul/tcpc/emul_tcpci_partner_src.c
+++ b/zephyr/emul/tcpc/emul_tcpci_partner_src.c
@@ -176,6 +176,22 @@ static void tcpci_src_emul_rx_consumed_op(
tcpci_partner_free_msg(msg);
}
+/**
+ * @brief Function called when emulator is disconnected from TCPCI
+ *
+ * @param emul Pointer to TCPCI emulator
+ * @param ops Pointer to partner operations structure
+ */
+static void tcpci_src_emul_disconnect_op(
+ const struct emul *emul,
+ const struct tcpci_emul_partner_ops *ops)
+{
+ struct tcpci_src_emul *src_emul =
+ CONTAINER_OF(ops, struct tcpci_src_emul, ops);
+
+ tcpci_partner_common_disconnect(&src_emul->common_data);
+}
+
/** Check description in emul_tcpci_partner_src.h */
int tcpci_src_emul_connect_to_tcpci(struct tcpci_src_emul_data *data,
struct tcpci_partner_data *common_data,
@@ -322,6 +338,7 @@ void tcpci_src_emul_init(struct tcpci_src_emul *emul)
emul->ops.transmit = tcpci_src_emul_transmit_op;
emul->ops.rx_consumed = tcpci_src_emul_rx_consumed_op;
emul->ops.control_change = NULL;
+ emul->ops.disconnect = tcpci_src_emul_disconnect_op;
tcpci_src_emul_init_data(&emul->data, &emul->common_data);
}
diff --git a/zephyr/include/emul/tcpc/emul_tcpci.h b/zephyr/include/emul/tcpc/emul_tcpci.h
index 41e15203c7..21f87680e8 100644
--- a/zephyr/include/emul/tcpc/emul_tcpci.h
+++ b/zephyr/include/emul/tcpc/emul_tcpci.h
@@ -184,6 +184,15 @@ struct tcpci_emul_partner_ops {
void (*rx_consumed)(const struct emul *emul,
const struct tcpci_emul_partner_ops *ops,
const struct tcpci_emul_msg *rx_msg);
+
+ /**
+ * @brief Function called when partner is disconnected from TCPCI
+ *
+ * @param emul Pointer to TCPCI emulator
+ * @param ops Pointer to partner operations structure
+ */
+ void (*disconnect)(const struct emul *emul,
+ const struct tcpci_emul_partner_ops *ops);
};
/**
diff --git a/zephyr/include/emul/tcpc/emul_tcpci_partner_common.h b/zephyr/include/emul/tcpc/emul_tcpci_partner_common.h
index d63a70c759..45e2edac6a 100644
--- a/zephyr/include/emul/tcpc/emul_tcpci_partner_common.h
+++ b/zephyr/include/emul/tcpc/emul_tcpci_partner_common.h
@@ -313,6 +313,15 @@ void tcpci_partner_common_handler_mask_msg(struct tcpci_partner_data *data,
bool enable);
/**
+ * @brief Common disconnect function which clears messages queue, sets
+ * tcpci_emul field in struct tcpci_partner_data to NULL, and stops
+ * timers.
+ *
+ * @param data Pointer to TCPCI partner emulator
+ */
+void tcpci_partner_common_disconnect(struct tcpci_partner_data *data);
+
+/**
* @brief Select if PD messages should be logged or not.
*
* @param data Pointer to TCPCI partner emulator
diff --git a/zephyr/test/drivers/src/integration/usbc/usb.c b/zephyr/test/drivers/src/integration/usbc/usb.c
index 83d0dabdd1..229b17e73c 100644
--- a/zephyr/test/drivers/src/integration/usbc/usb.c
+++ b/zephyr/test/drivers/src/integration/usbc/usb.c
@@ -133,6 +133,7 @@ ZTEST(integration_usb, test_attach_drp)
* TODO: Change it to examining EC_CMD_TYPEC_STATUS
*/
zassert_equal(PE_SNK_READY, get_state_pe(USBC_PORT_C0), NULL);
+ zassert_ok(tcpci_emul_disconnect_partner(tcpci_emul), NULL);
}
ZTEST_SUITE(integration_usb, drivers_predicate_post_main, NULL,