git: 9342829d578e - main - scmi: Make transports report the effective length of the received messages
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 23 Jan 2025 17:27:31 UTC
The branch main has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=9342829d578e26f10a5cbc26e2b9e66cfd9864c4 commit 9342829d578e26f10a5cbc26e2b9e66cfd9864c4 Author: Cristian Marussi <cristian.marussi@arm.com> AuthorDate: 2025-01-23 12:49:02 +0000 Commit: Andrew Turner <andrew@FreeBSD.org> CommitDate: 2025-01-23 17:26:26 +0000 scmi: Make transports report the effective length of the received messages Once a message is received that fits into the RX buffer, update the msg.rx_len field with the effective length of the message received. Tested on: Arm Morello Board Reviewed by: andrew Sponsored by: Arm Ltd Pull Request: https://reviews.freebsd.org/D47420 Signed-off-by: Cristian Marussi <cristian.marussi@arm.com> --- sys/dev/firmware/arm/scmi.c | 10 ++++++---- sys/dev/firmware/arm/scmi.h | 2 +- sys/dev/firmware/arm/scmi_mailbox.c | 10 +++++----- sys/dev/firmware/arm/scmi_shmem.c | 22 +++++++++------------- sys/dev/firmware/arm/scmi_shmem.h | 6 +++--- sys/dev/firmware/arm/scmi_smc.c | 4 ++-- sys/dev/firmware/arm/scmi_virtio.c | 5 ++--- 7 files changed, 28 insertions(+), 31 deletions(-) diff --git a/sys/dev/firmware/arm/scmi.c b/sys/dev/firmware/arm/scmi.c index 37496136c828..00a229762414 100644 --- a/sys/dev/firmware/arm/scmi.c +++ b/sys/dev/firmware/arm/scmi.c @@ -146,7 +146,8 @@ static struct scmi_req *scmi_req_lookup_inflight(struct scmi_softc *, uint32_t); static int scmi_wait_for_response(struct scmi_softc *, struct scmi_req *, void **); -static void scmi_process_response(struct scmi_softc *, uint32_t); +static void scmi_process_response(struct scmi_softc *, uint32_t, + unsigned int); int scmi_attach(device_t dev) @@ -469,7 +470,7 @@ scmi_req_lookup_inflight(struct scmi_softc *sc, uint32_t hdr) } static void -scmi_process_response(struct scmi_softc *sc, uint32_t hdr) +scmi_process_response(struct scmi_softc *sc, uint32_t hdr, uint32_t rx_len) { bool timed_out = false; struct scmi_req *req; @@ -484,6 +485,7 @@ scmi_process_response(struct scmi_softc *sc, uint32_t hdr) mtx_lock_spin(&req->mtx); req->done = true; + req->msg.rx_len = rx_len; if (!req->timed_out) { /* * Consider the case in which a polled message is picked @@ -512,7 +514,7 @@ scmi_process_response(struct scmi_softc *sc, uint32_t hdr) } void -scmi_rx_irq_callback(device_t dev, void *chan, uint32_t hdr) +scmi_rx_irq_callback(device_t dev, void *chan, uint32_t hdr, uint32_t rx_len) { struct scmi_softc *sc; @@ -524,7 +526,7 @@ scmi_rx_irq_callback(device_t dev, void *chan, uint32_t hdr) return; } - scmi_process_response(sc, hdr); + scmi_process_response(sc, hdr, rx_len); } static int diff --git a/sys/dev/firmware/arm/scmi.h b/sys/dev/firmware/arm/scmi.h index 345ae6eeb03a..5ad7b0db3f5f 100644 --- a/sys/dev/firmware/arm/scmi.h +++ b/sys/dev/firmware/arm/scmi.h @@ -75,7 +75,7 @@ void *scmi_buf_get(device_t dev, uint8_t protocol_id, uint8_t message_id, int tx_payd_sz, int rx_payld_sz); void scmi_buf_put(device_t dev, void *buf); int scmi_request(device_t dev, void *in, void **); -void scmi_rx_irq_callback(device_t dev, void *chan, uint32_t hdr); +void scmi_rx_irq_callback(device_t dev, void *chan, uint32_t hdr, uint32_t rx_len); DECLARE_CLASS(scmi_driver); diff --git a/sys/dev/firmware/arm/scmi_mailbox.c b/sys/dev/firmware/arm/scmi_mailbox.c index 858b81f68845..d7b642b69b85 100644 --- a/sys/dev/firmware/arm/scmi_mailbox.c +++ b/sys/dev/firmware/arm/scmi_mailbox.c @@ -70,14 +70,14 @@ static void scmi_mailbox_a2p_callback(void *arg) { struct scmi_mailbox_softc *sc; - uint32_t msg_header; + uint32_t msg_header, rx_len; int ret; sc = arg; - ret = scmi_shmem_read_msg_header(sc->a2p_dev, &msg_header); + ret = scmi_shmem_read_msg_header(sc->a2p_dev, &msg_header, &rx_len); if (ret == 0) - scmi_rx_irq_callback(sc->base.dev, sc->a2p_dev, msg_header); + scmi_rx_irq_callback(sc->base.dev, sc->a2p_dev, msg_header, rx_len); } static int @@ -154,7 +154,7 @@ scmi_mailbox_poll_msg(device_t dev, struct scmi_msg *msg, unsigned int tmo_ms) sc = device_get_softc(dev); do { - if (scmi_shmem_poll_msg(sc->a2p_dev, &msg->hdr)) + if (scmi_shmem_poll_msg(sc->a2p_dev, &msg->hdr, &msg->rx_len)) break; DELAY(SCMI_MBOX_POLL_INTERVAL_MS * 1000); } while (tmo_loops--); @@ -171,7 +171,7 @@ scmi_mailbox_collect_reply(device_t dev, struct scmi_msg *msg) sc = device_get_softc(dev); ret = scmi_shmem_read_msg_payload(sc->a2p_dev, - msg->payld, msg->rx_len - SCMI_MSG_HDR_SIZE); + msg->payld, msg->rx_len - SCMI_MSG_HDR_SIZE, msg->rx_len); return (ret); } diff --git a/sys/dev/firmware/arm/scmi_shmem.c b/sys/dev/firmware/arm/scmi_shmem.c index 9bab4bc4004e..a63d96b64cb5 100644 --- a/sys/dev/firmware/arm/scmi_shmem.c +++ b/sys/dev/firmware/arm/scmi_shmem.c @@ -247,7 +247,7 @@ scmi_shmem_clear_channel(device_t dev) } int -scmi_shmem_read_msg_header(device_t dev, uint32_t *msg_header) +scmi_shmem_read_msg_header(device_t dev, uint32_t *msg_header, unsigned int *rx_len) { uint32_t length, header; @@ -256,6 +256,7 @@ scmi_shmem_read_msg_header(device_t dev, uint32_t *msg_header) if (le32toh(length) < sizeof(header)) return (EINVAL); + *rx_len = le32toh(length); /* Read header. */ scmi_shmem_read(dev, SMT_OFFSET_MSG_HEADER, &header, SMT_SIZE_MSG_HEADER); @@ -266,14 +267,11 @@ scmi_shmem_read_msg_header(device_t dev, uint32_t *msg_header) } int -scmi_shmem_read_msg_payload(device_t dev, uint8_t *buf, uint32_t buf_len) +scmi_shmem_read_msg_payload(device_t dev, uint8_t *buf, uint32_t buf_len, uint32_t rx_len) { - uint32_t length, payld_len; - - /* Read length. */ - scmi_shmem_read(dev, SMT_OFFSET_LENGTH, &length, SMT_SIZE_LENGTH); - payld_len = le32toh(length) - SCMI_MSG_HDR_SIZE; + uint32_t payld_len; + payld_len = rx_len - SCMI_MSG_HDR_SIZE; if (payld_len > buf_len) { device_printf(dev, "RX payload %dbytes exceeds buflen %dbytes. Truncate.\n", @@ -296,7 +294,7 @@ scmi_shmem_tx_complete(device_t dev) scmi_shmem_release_channel(sc); } -bool scmi_shmem_poll_msg(device_t dev, uint32_t *msg_header) +bool scmi_shmem_poll_msg(device_t dev, uint32_t *msg_header, uint32_t *rx_len) { uint32_t status; bool ret; @@ -306,12 +304,10 @@ bool scmi_shmem_poll_msg(device_t dev, uint32_t *msg_header) ret = (status & (SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR | SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE)); + if (ret == 0) + return (ret); - if (ret) - scmi_shmem_read(dev, SMT_OFFSET_MSG_HEADER, msg_header, - SMT_SIZE_MSG_HEADER); - - return (ret); + return (scmi_shmem_read_msg_header(dev, msg_header, rx_len)); } static device_method_t shmem_methods[] = { diff --git a/sys/dev/firmware/arm/scmi_shmem.h b/sys/dev/firmware/arm/scmi_shmem.h index ed8763d5c145..bc8284502129 100644 --- a/sys/dev/firmware/arm/scmi_shmem.h +++ b/sys/dev/firmware/arm/scmi_shmem.h @@ -63,9 +63,9 @@ struct scmi_smt_header { device_t scmi_shmem_get(device_t sdev, phandle_t node, int index); int scmi_shmem_prepare_msg(device_t dev, uint8_t *msg, uint32_t tx_len, bool polling); -bool scmi_shmem_poll_msg(device_t dev, uint32_t *msg_header); -int scmi_shmem_read_msg_header(device_t dev, uint32_t *msg_header); -int scmi_shmem_read_msg_payload(device_t dev, uint8_t *buf, uint32_t buf_len); +bool scmi_shmem_poll_msg(device_t dev, uint32_t *msg_header, uint32_t *rx_len); +int scmi_shmem_read_msg_header(device_t dev, uint32_t *msg_header, uint32_t *rx_len); +int scmi_shmem_read_msg_payload(device_t dev, uint8_t *buf, uint32_t buf_len, uint32_t rx_len); void scmi_shmem_tx_complete(device_t); void scmi_shmem_clear_channel(device_t); diff --git a/sys/dev/firmware/arm/scmi_smc.c b/sys/dev/firmware/arm/scmi_smc.c index 9f0d899233fa..81c66ad7bb46 100644 --- a/sys/dev/firmware/arm/scmi_smc.c +++ b/sys/dev/firmware/arm/scmi_smc.c @@ -122,7 +122,7 @@ scmi_smc_poll_msg(device_t dev, struct scmi_msg *msg, unsigned int tmo) * Nothing to poll since commands are completed as soon as smc * returns ... but did we get back what we were poling for ? */ - scmi_shmem_read_msg_header(sc->a2p_dev, &msg->hdr); + scmi_shmem_read_msg_header(sc->a2p_dev, &msg->hdr, &msg->rx_len); return (0); } @@ -136,7 +136,7 @@ scmi_smc_collect_reply(device_t dev, struct scmi_msg *msg) sc = device_get_softc(dev); ret = scmi_shmem_read_msg_payload(sc->a2p_dev, - msg->payld, msg->rx_len - SCMI_MSG_HDR_SIZE); + msg->payld, msg->rx_len - SCMI_MSG_HDR_SIZE, msg->rx_len); return (ret); } diff --git a/sys/dev/firmware/arm/scmi_virtio.c b/sys/dev/firmware/arm/scmi_virtio.c index 12cbb9ecefd5..8714fee2ec87 100644 --- a/sys/dev/firmware/arm/scmi_virtio.c +++ b/sys/dev/firmware/arm/scmi_virtio.c @@ -76,7 +76,7 @@ scmi_virtio_callback(void *msg, unsigned int len, void *priv) } hdr = le32toh(*((uint32_t *)msg)); - scmi_rx_irq_callback(sc->base.dev, msg, hdr); + scmi_rx_irq_callback(sc->base.dev, msg, hdr, len); } static void * @@ -225,7 +225,6 @@ scmi_virtio_poll_msg(device_t dev, struct scmi_msg *msg, unsigned int tmo_ms) } rx_msg = hdr_to_msg(rx_buf); - rx_msg->rx_len = rx_len; /* Complete the polling on any poll path */ if (rx_msg->polling) atomic_store_rel_int(&rx_msg->poll_done, 1); @@ -242,7 +241,7 @@ scmi_virtio_poll_msg(device_t dev, struct scmi_msg *msg, unsigned int tmo_ms) rx_msg->hdr, rx_msg->polling); if (!rx_msg->polling) - scmi_rx_irq_callback(sc->base.dev, rx_msg, rx_msg->hdr); + scmi_rx_irq_callback(sc->base.dev, rx_msg, rx_msg->hdr, rx_len); } return (tmo_loops > 0 ? 0 : ETIMEDOUT);